summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk1
-rw-r--r--api/current.txt51
-rw-r--r--api/system-current.txt39
-rw-r--r--cmds/am/src/com/android/commands/am/Am.java2
-rw-r--r--cmds/pm/src/com/android/commands/pm/Pm.java25
-rw-r--r--core/java/android/accounts/AccountManager.java6
-rw-r--r--core/java/android/app/Activity.java22
-rw-r--r--core/java/android/app/ActivityManagerNative.java40
-rw-r--r--core/java/android/app/AppOpsManager.java139
-rw-r--r--core/java/android/app/BackStackRecord.java3
-rw-r--r--core/java/android/app/ContextImpl.java10
-rw-r--r--core/java/android/app/IActivityManager.java15
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java61
-rw-r--r--core/java/android/app/assist/AssistContent.java1
-rw-r--r--core/java/android/app/assist/AssistStructure.java286
-rw-r--r--core/java/android/app/usage/UsageEvents.java9
-rw-r--r--core/java/android/content/BroadcastReceiver.java2
-rw-r--r--core/java/android/content/ContentProvider.java24
-rw-r--r--core/java/android/content/ContentResolver.java12
-rw-r--r--core/java/android/content/Intent.java11
-rw-r--r--core/java/android/content/IntentFilter.java41
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl8
-rw-r--r--core/java/android/content/pm/IPackagesProvider.aidl22
-rw-r--r--core/java/android/content/pm/PackageManagerInternal.java46
-rw-r--r--core/java/android/content/pm/PackageParser.java3
-rw-r--r--core/java/android/content/pm/PermissionInfo.java10
-rw-r--r--core/java/android/hardware/SensorManager.java49
-rw-r--r--core/java/android/hardware/SystemSensorManager.java58
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java156
-rw-r--r--core/java/android/hardware/camera2/CameraDevice.java17
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java2
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java17
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java17
-rw-r--r--core/java/android/hardware/fingerprint/IFingerprintService.aidl2
-rw-r--r--core/java/android/net/ConnectivityManager.java15
-rw-r--r--core/java/android/net/LinkProperties.java39
-rw-r--r--core/java/android/nfc/NfcActivityManager.java2
-rw-r--r--core/java/android/nfc/cardemulation/CardEmulation.java2
-rw-r--r--core/java/android/os/BatteryStats.java26
-rw-r--r--core/java/android/os/Build.java2
-rw-r--r--core/java/android/os/DeadObjectException.java4
-rw-r--r--core/java/android/os/Process.java11
-rw-r--r--core/java/android/os/UserHandle.java24
-rw-r--r--core/java/android/os/UserManager.java15
-rw-r--r--core/java/android/os/storage/DiskInfo.java5
-rw-r--r--core/java/android/os/storage/IMountService.java26
-rw-r--r--core/java/android/os/storage/StorageManager.java9
-rw-r--r--core/java/android/os/storage/VolumeRecord.java14
-rw-r--r--core/java/android/provider/Settings.java26
-rw-r--r--core/java/android/service/notification/NotificationListenerService.java4
-rw-r--r--core/java/android/service/voice/VoiceInteractionService.java9
-rw-r--r--core/java/android/service/voice/VoiceInteractionSession.java210
-rw-r--r--core/java/android/service/voice/VoiceInteractionSessionService.java2
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java7
-rw-r--r--core/java/android/speech/tts/TextToSpeech.java15
-rw-r--r--core/java/android/speech/tts/TextToSpeechService.java4
-rw-r--r--core/java/android/text/StaticLayout.java21
-rw-r--r--core/java/android/text/format/Formatter.java41
-rw-r--r--core/java/android/text/method/WordIterator.java104
-rw-r--r--core/java/android/transition/Transition.java30
-rw-r--r--core/java/android/transition/TransitionManager.java9
-rw-r--r--core/java/android/transition/Visibility.java1
-rw-r--r--core/java/android/util/LocalLog.java14
-rw-r--r--core/java/android/util/TimeUtils.java12
-rw-r--r--core/java/android/view/ActionProvider.java8
-rw-r--r--core/java/android/view/IWindowSession.aidl2
-rw-r--r--core/java/android/view/ThreadedRenderer.java17
-rw-r--r--core/java/android/view/View.java35
-rw-r--r--core/java/android/view/ViewGroup.java28
-rw-r--r--core/java/android/view/ViewRootImpl.java4
-rw-r--r--core/java/android/view/ViewStructure.java23
-rw-r--r--core/java/android/view/WindowManagerPolicy.java13
-rw-r--r--core/java/android/view/accessibility/AccessibilityEvent.java12
-rw-r--r--core/java/android/widget/AbsListView.java20
-rw-r--r--core/java/android/widget/AppSecurityPermissions.java3
-rw-r--r--core/java/android/widget/CompoundButton.java11
-rw-r--r--core/java/android/widget/Editor.java287
-rw-r--r--core/java/android/widget/ImageView.java26
-rw-r--r--core/java/android/widget/LinearLayout.java51
-rw-r--r--core/java/android/widget/ListView.java40
-rw-r--r--core/java/android/widget/TextView.java95
-rw-r--r--core/java/com/android/internal/app/ExternalMediaFormatActivity.java108
-rw-r--r--core/java/com/android/internal/app/IAppOpsService.aidl2
-rw-r--r--core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl1
-rw-r--r--core/java/com/android/internal/app/IntentForwarderActivity.java4
-rw-r--r--core/java/com/android/internal/app/MediaRouteControllerDialog.java6
-rw-r--r--core/java/com/android/internal/inputmethod/InputMethodUtils.java127
-rw-r--r--core/java/com/android/internal/logging/MetricsLogger.java4
-rw-r--r--core/java/com/android/internal/os/BatteryStatsHelper.java17
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java21
-rw-r--r--core/java/com/android/internal/os/KernelUidCpuTimeReader.java50
-rw-r--r--core/java/com/android/internal/os/Zygote.java6
-rw-r--r--core/java/com/android/internal/os/ZygoteConnection.java4
-rw-r--r--core/java/com/android/internal/os/storage/ExternalStorageFormatter.java4
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBarService.aidl2
-rw-r--r--core/java/com/android/internal/view/FloatingActionMode.java19
-rw-r--r--core/java/com/android/internal/view/menu/MenuItemImpl.java2
-rw-r--r--core/java/com/android/internal/widget/DrawingSpace.java76
-rw-r--r--core/java/com/android/internal/widget/FloatingToolbar.java113
-rw-r--r--core/java/com/android/internal/widget/ViewPager.java2
-rw-r--r--core/jni/android_hardware_SensorManager.cpp12
-rw-r--r--core/jni/android_util_Binder.cpp22
-rw-r--r--core/jni/com_android_internal_os_Zygote.cpp101
-rw-r--r--core/res/AndroidManifest.xml425
-rw-r--r--core/res/res/drawable-hdpi/perm_group_accounts.pngbin714 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/perm_group_accounts.pngbin528 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/perm_group_accounts.pngbin814 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_perm_group_accounts.pngbin1096 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_perm_group_storage.pngbin1040 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/perm_group_accounts.pngbin1131 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/perm_group_accounts.pngbin1539 -> 0 bytes
-rw-r--r--core/res/res/drawable/perm_group_storage.xml11
-rw-r--r--core/res/res/layout-land/time_picker_material.xml2
-rw-r--r--core/res/res/layout/date_picker_view_animator_material.xml3
-rw-r--r--core/res/res/layout/floating_popup_menu_button.xml3
-rw-r--r--core/res/res/layout/year_label_text_view.xml2
-rw-r--r--core/res/res/values-af/strings.xml6
-rw-r--r--core/res/res/values-am/strings.xml6
-rw-r--r--core/res/res/values-ar/strings.xml6
-rw-r--r--core/res/res/values-az-rAZ/strings.xml6
-rw-r--r--core/res/res/values-bg/strings.xml6
-rw-r--r--core/res/res/values-bn-rBD/strings.xml8
-rw-r--r--core/res/res/values-ca/strings.xml8
-rw-r--r--core/res/res/values-cs/strings.xml8
-rw-r--r--core/res/res/values-da/strings.xml14
-rw-r--r--core/res/res/values-de/strings.xml10
-rw-r--r--core/res/res/values-el/strings.xml6
-rw-r--r--core/res/res/values-en-rAU/strings.xml6
-rw-r--r--core/res/res/values-en-rGB/strings.xml6
-rw-r--r--core/res/res/values-en-rIN/strings.xml6
-rw-r--r--core/res/res/values-es-rUS/strings.xml6
-rw-r--r--core/res/res/values-es/strings.xml6
-rw-r--r--core/res/res/values-et-rEE/strings.xml6
-rw-r--r--core/res/res/values-eu-rES/strings.xml6
-rw-r--r--core/res/res/values-fa/strings.xml6
-rw-r--r--core/res/res/values-fi/strings.xml6
-rw-r--r--core/res/res/values-fr-rCA/strings.xml6
-rw-r--r--core/res/res/values-fr/strings.xml20
-rw-r--r--core/res/res/values-gl-rES/strings.xml6
-rw-r--r--core/res/res/values-gu-rIN/strings.xml6
-rw-r--r--core/res/res/values-hi/strings.xml6
-rw-r--r--core/res/res/values-hr/strings.xml6
-rw-r--r--core/res/res/values-hu/strings.xml6
-rw-r--r--core/res/res/values-hy-rAM/strings.xml6
-rw-r--r--core/res/res/values-in/strings.xml6
-rw-r--r--core/res/res/values-is-rIS/strings.xml6
-rw-r--r--core/res/res/values-it/strings.xml6
-rw-r--r--core/res/res/values-iw/strings.xml12
-rw-r--r--core/res/res/values-ja/strings.xml10
-rw-r--r--core/res/res/values-ka-rGE/strings.xml6
-rw-r--r--core/res/res/values-kk-rKZ/strings.xml6
-rw-r--r--core/res/res/values-km-rKH/strings.xml6
-rw-r--r--core/res/res/values-kn-rIN/strings.xml6
-rw-r--r--core/res/res/values-ko/strings.xml6
-rw-r--r--core/res/res/values-ky-rKG/strings.xml8
-rw-r--r--core/res/res/values-lo-rLA/strings.xml6
-rw-r--r--core/res/res/values-lt/strings.xml8
-rw-r--r--core/res/res/values-lv/strings.xml16
-rw-r--r--core/res/res/values-mk-rMK/strings.xml6
-rw-r--r--core/res/res/values-ml-rIN/strings.xml6
-rw-r--r--core/res/res/values-mn-rMN/strings.xml6
-rw-r--r--core/res/res/values-mr-rIN/strings.xml6
-rw-r--r--core/res/res/values-ms-rMY/strings.xml6
-rw-r--r--core/res/res/values-my-rMM/strings.xml6
-rw-r--r--core/res/res/values-nb/strings.xml6
-rw-r--r--core/res/res/values-ne-rNP/strings.xml6
-rw-r--r--core/res/res/values-nl/strings.xml6
-rw-r--r--core/res/res/values-pa-rIN/strings.xml6
-rw-r--r--core/res/res/values-pl/strings.xml10
-rw-r--r--core/res/res/values-pt-rPT/strings.xml6
-rw-r--r--core/res/res/values-pt/strings.xml6
-rw-r--r--core/res/res/values-ro/strings.xml8
-rw-r--r--core/res/res/values-ru/strings.xml6
-rw-r--r--core/res/res/values-si-rLK/strings.xml8
-rw-r--r--core/res/res/values-sk/strings.xml12
-rw-r--r--core/res/res/values-sl/strings.xml6
-rw-r--r--core/res/res/values-sq-rAL/strings.xml6
-rw-r--r--core/res/res/values-sr/strings.xml6
-rw-r--r--core/res/res/values-sv/strings.xml12
-rw-r--r--core/res/res/values-sw/strings.xml6
-rw-r--r--core/res/res/values-ta-rIN/strings.xml6
-rw-r--r--core/res/res/values-te-rIN/strings.xml6
-rw-r--r--core/res/res/values-th/strings.xml6
-rw-r--r--core/res/res/values-tl/strings.xml6
-rw-r--r--core/res/res/values-tr/strings.xml6
-rw-r--r--core/res/res/values-uk/strings.xml6
-rw-r--r--core/res/res/values-ur-rPK/strings.xml10
-rw-r--r--core/res/res/values-uz-rUZ/strings.xml6
-rw-r--r--core/res/res/values-vi/strings.xml6
-rw-r--r--core/res/res/values-zh-rCN/strings.xml6
-rw-r--r--core/res/res/values-zh-rHK/strings.xml6
-rw-r--r--core/res/res/values-zh-rTW/strings.xml6
-rw-r--r--core/res/res/values-zu/strings.xml6
-rw-r--r--core/res/res/values/attrs.xml5
-rw-r--r--core/res/res/values/attrs_manifest.xml5
-rwxr-xr-xcore/res/res/values/config.xml13
-rw-r--r--core/res/res/values/strings.xml20
-rwxr-xr-xcore/res/res/values/symbols.xml8
-rw-r--r--core/res/res/values/themes.xml2
-rw-r--r--core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk2
-rw-r--r--core/tests/coretests/src/android/net/LinkPropertiesTest.java79
-rw-r--r--core/tests/coretests/src/android/text/format/FormatterTest.java104
-rw-r--r--core/tests/inputmethodtests/src/android/os/InputMethodTest.java99
-rw-r--r--data/etc/platform.xml15
-rw-r--r--docs/html-intl/intl/es/design/get-started/principles.jd307
-rw-r--r--docs/html-intl/intl/es/design/material/index.jd186
-rw-r--r--docs/html-intl/intl/es/design/patterns/confirming-acknowledging.jd70
-rw-r--r--docs/html-intl/intl/es/design/patterns/navigation.jd213
-rw-r--r--docs/html-intl/intl/es/design/patterns/notifications.jd872
-rw-r--r--docs/html-intl/intl/es/preview/api-overview.jd521
-rw-r--r--docs/html-intl/intl/es/preview/behavior-changes.jd403
-rw-r--r--docs/html-intl/intl/es/preview/features/runtime-permissions.jd794
-rw-r--r--docs/html-intl/intl/es/preview/overview.jd362
-rw-r--r--docs/html-intl/intl/ja/design/get-started/principles.jd307
-rw-r--r--docs/html-intl/intl/ja/design/material/index.jd186
-rw-r--r--docs/html-intl/intl/ja/design/patterns/confirming-acknowledging.jd70
-rw-r--r--docs/html-intl/intl/ja/design/patterns/navigation.jd213
-rw-r--r--docs/html-intl/intl/ja/design/patterns/notifications.jd872
-rw-r--r--docs/html-intl/intl/ja/preview/api-overview.jd521
-rw-r--r--docs/html-intl/intl/ja/preview/behavior-changes.jd402
-rw-r--r--docs/html-intl/intl/ja/preview/features/runtime-permissions.jd794
-rw-r--r--docs/html-intl/intl/ja/preview/overview.jd362
-rw-r--r--docs/html-intl/intl/ja/training/basics/activity-lifecycle/index.jd72
-rw-r--r--docs/html-intl/intl/ja/training/basics/activity-lifecycle/pausing.jd147
-rw-r--r--docs/html-intl/intl/ja/training/basics/activity-lifecycle/recreating.jd178
-rw-r--r--docs/html-intl/intl/ja/training/basics/activity-lifecycle/starting.jd285
-rw-r--r--docs/html-intl/intl/ja/training/basics/activity-lifecycle/stopping.jd187
-rw-r--r--docs/html-intl/intl/ja/training/basics/data-storage/databases.jd317
-rw-r--r--docs/html-intl/intl/ja/training/basics/data-storage/files.jd379
-rw-r--r--docs/html-intl/intl/ja/training/basics/data-storage/index.jd57
-rw-r--r--docs/html-intl/intl/ja/training/basics/data-storage/shared-preferences.jd120
-rw-r--r--docs/html-intl/intl/ja/training/basics/intents/filters.jd236
-rw-r--r--docs/html-intl/intl/ja/training/basics/intents/index.jd62
-rw-r--r--docs/html-intl/intl/ja/training/basics/intents/result.jd178
-rw-r--r--docs/html-intl/intl/ja/training/basics/intents/sending.jd256
-rw-r--r--docs/html-intl/intl/ko/design/get-started/principles.jd307
-rw-r--r--docs/html-intl/intl/ko/design/material/index.jd186
-rw-r--r--docs/html-intl/intl/ko/design/patterns/confirming-acknowledging.jd70
-rw-r--r--docs/html-intl/intl/ko/design/patterns/navigation.jd213
-rw-r--r--docs/html-intl/intl/ko/design/patterns/notifications.jd872
-rw-r--r--docs/html-intl/intl/ko/preview/api-overview.jd521
-rw-r--r--docs/html-intl/intl/ko/preview/behavior-changes.jd402
-rw-r--r--docs/html-intl/intl/ko/preview/features/runtime-permissions.jd794
-rw-r--r--docs/html-intl/intl/ko/preview/overview.jd362
-rw-r--r--docs/html-intl/intl/ko/training/basics/activity-lifecycle/index.jd72
-rw-r--r--docs/html-intl/intl/ko/training/basics/activity-lifecycle/pausing.jd147
-rw-r--r--docs/html-intl/intl/ko/training/basics/activity-lifecycle/recreating.jd178
-rw-r--r--docs/html-intl/intl/ko/training/basics/activity-lifecycle/starting.jd285
-rw-r--r--docs/html-intl/intl/ko/training/basics/activity-lifecycle/stopping.jd187
-rw-r--r--docs/html-intl/intl/ko/training/basics/data-storage/databases.jd317
-rw-r--r--docs/html-intl/intl/ko/training/basics/data-storage/files.jd379
-rw-r--r--docs/html-intl/intl/ko/training/basics/data-storage/index.jd57
-rw-r--r--docs/html-intl/intl/ko/training/basics/data-storage/shared-preferences.jd120
-rw-r--r--docs/html-intl/intl/ko/training/basics/intents/filters.jd236
-rw-r--r--docs/html-intl/intl/ko/training/basics/intents/index.jd62
-rw-r--r--docs/html-intl/intl/ko/training/basics/intents/result.jd178
-rw-r--r--docs/html-intl/intl/ko/training/basics/intents/sending.jd256
-rw-r--r--docs/html-intl/intl/pt-br/design/get-started/principles.jd307
-rw-r--r--docs/html-intl/intl/pt-br/design/material/index.jd186
-rw-r--r--docs/html-intl/intl/pt-br/design/patterns/confirming-acknowledging.jd70
-rw-r--r--docs/html-intl/intl/pt-br/design/patterns/navigation.jd213
-rw-r--r--docs/html-intl/intl/pt-br/design/patterns/notifications.jd872
-rw-r--r--docs/html-intl/intl/pt-br/preview/api-overview.jd521
-rw-r--r--docs/html-intl/intl/pt-br/preview/behavior-changes.jd402
-rw-r--r--docs/html-intl/intl/pt-br/preview/features/runtime-permissions.jd794
-rw-r--r--docs/html-intl/intl/pt-br/preview/images/direct-share-screen.pngbin0 -> 57767 bytes
-rw-r--r--docs/html-intl/intl/pt-br/preview/images/direct-share-screen_2x.pngbin0 -> 195946 bytes
-rw-r--r--docs/html-intl/intl/pt-br/preview/images/fingerprint-screen.pngbin0 -> 39082 bytes
-rw-r--r--docs/html-intl/intl/pt-br/preview/images/fingerprint-screen_2x.pngbin0 -> 127518 bytes
-rw-r--r--docs/html-intl/intl/pt-br/preview/images/m-preview-timeline-crop.pngbin0 -> 10205 bytes
-rw-r--r--docs/html-intl/intl/pt-br/preview/images/m-preview-timeline.pngbin0 -> 13002 bytes
-rw-r--r--docs/html-intl/intl/pt-br/preview/images/perf-test-frame-latency.pngbin0 -> 161802 bytes
-rw-r--r--docs/html-intl/intl/pt-br/preview/images/perf-test-framestats.pngbin0 -> 7785 bytes
-rw-r--r--docs/html-intl/intl/pt-br/preview/images/text-selection.gifbin0 -> 212462 bytes
-rw-r--r--docs/html-intl/intl/pt-br/preview/images/work-profile-screen.pngbin0 -> 39183 bytes
-rw-r--r--docs/html-intl/intl/pt-br/preview/images/work-profile-screen_2x.pngbin0 -> 126304 bytes
-rw-r--r--docs/html-intl/intl/pt-br/preview/overview.jd362
-rw-r--r--docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/index.jd72
-rw-r--r--docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/pausing.jd147
-rw-r--r--docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/recreating.jd178
-rw-r--r--docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/starting.jd285
-rw-r--r--docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/stopping.jd187
-rw-r--r--docs/html-intl/intl/pt-br/training/basics/data-storage/databases.jd317
-rw-r--r--docs/html-intl/intl/pt-br/training/basics/data-storage/files.jd379
-rw-r--r--docs/html-intl/intl/pt-br/training/basics/data-storage/index.jd57
-rw-r--r--docs/html-intl/intl/pt-br/training/basics/data-storage/shared-preferences.jd120
-rw-r--r--docs/html-intl/intl/pt-br/training/basics/intents/filters.jd236
-rw-r--r--docs/html-intl/intl/pt-br/training/basics/intents/index.jd62
-rw-r--r--docs/html-intl/intl/pt-br/training/basics/intents/result.jd178
-rw-r--r--docs/html-intl/intl/pt-br/training/basics/intents/sending.jd256
-rw-r--r--docs/html-intl/intl/ru/design/get-started/principles.jd307
-rw-r--r--docs/html-intl/intl/ru/design/material/index.jd186
-rw-r--r--docs/html-intl/intl/ru/design/patterns/confirming-acknowledging.jd70
-rw-r--r--docs/html-intl/intl/ru/design/patterns/navigation.jd213
-rw-r--r--docs/html-intl/intl/ru/design/patterns/notifications.jd872
-rw-r--r--docs/html-intl/intl/ru/preview/api-overview.jd521
-rw-r--r--docs/html-intl/intl/ru/preview/behavior-changes.jd402
-rw-r--r--docs/html-intl/intl/ru/preview/features/runtime-permissions.jd794
-rw-r--r--docs/html-intl/intl/ru/preview/overview.jd362
-rw-r--r--docs/html-intl/intl/ru/training/basics/activity-lifecycle/index.jd72
-rw-r--r--docs/html-intl/intl/ru/training/basics/activity-lifecycle/pausing.jd147
-rw-r--r--docs/html-intl/intl/ru/training/basics/activity-lifecycle/recreating.jd178
-rw-r--r--docs/html-intl/intl/ru/training/basics/activity-lifecycle/starting.jd285
-rw-r--r--docs/html-intl/intl/ru/training/basics/activity-lifecycle/stopping.jd187
-rw-r--r--docs/html-intl/intl/ru/training/basics/data-storage/databases.jd317
-rw-r--r--docs/html-intl/intl/ru/training/basics/data-storage/files.jd379
-rw-r--r--docs/html-intl/intl/ru/training/basics/data-storage/index.jd57
-rw-r--r--docs/html-intl/intl/ru/training/basics/data-storage/shared-preferences.jd120
-rw-r--r--docs/html-intl/intl/ru/training/basics/intents/filters.jd236
-rw-r--r--docs/html-intl/intl/ru/training/basics/intents/index.jd62
-rw-r--r--docs/html-intl/intl/ru/training/basics/intents/result.jd178
-rw-r--r--docs/html-intl/intl/ru/training/basics/intents/sending.jd256
-rw-r--r--docs/html-intl/intl/zh-cn/design/get-started/principles.jd307
-rw-r--r--docs/html-intl/intl/zh-cn/design/material/index.jd186
-rw-r--r--docs/html-intl/intl/zh-cn/design/patterns/confirming-acknowledging.jd70
-rw-r--r--docs/html-intl/intl/zh-cn/design/patterns/navigation.jd213
-rw-r--r--docs/html-intl/intl/zh-cn/design/patterns/notifications.jd872
-rw-r--r--docs/html-intl/intl/zh-cn/preview/api-overview.jd521
-rw-r--r--docs/html-intl/intl/zh-cn/preview/behavior-changes.jd402
-rw-r--r--docs/html-intl/intl/zh-cn/preview/features/runtime-permissions.jd794
-rw-r--r--docs/html-intl/intl/zh-cn/preview/overview.jd362
-rw-r--r--docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/index.jd72
-rw-r--r--docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/pausing.jd147
-rw-r--r--docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/recreating.jd178
-rw-r--r--docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/starting.jd285
-rw-r--r--docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/stopping.jd187
-rw-r--r--docs/html-intl/intl/zh-cn/training/basics/data-storage/databases.jd317
-rw-r--r--docs/html-intl/intl/zh-cn/training/basics/data-storage/files.jd379
-rw-r--r--docs/html-intl/intl/zh-cn/training/basics/data-storage/index.jd57
-rw-r--r--docs/html-intl/intl/zh-cn/training/basics/data-storage/shared-preferences.jd120
-rw-r--r--docs/html-intl/intl/zh-cn/training/basics/intents/filters.jd236
-rw-r--r--docs/html-intl/intl/zh-cn/training/basics/intents/index.jd62
-rw-r--r--docs/html-intl/intl/zh-cn/training/basics/intents/result.jd178
-rw-r--r--docs/html-intl/intl/zh-cn/training/basics/intents/sending.jd256
-rw-r--r--docs/html-intl/intl/zh-tw/design/get-started/principles.jd307
-rw-r--r--docs/html-intl/intl/zh-tw/design/material/index.jd186
-rw-r--r--docs/html-intl/intl/zh-tw/design/patterns/confirming-acknowledging.jd70
-rw-r--r--docs/html-intl/intl/zh-tw/design/patterns/navigation.jd213
-rw-r--r--docs/html-intl/intl/zh-tw/design/patterns/notifications.jd872
-rw-r--r--docs/html-intl/intl/zh-tw/preview/api-overview.jd521
-rw-r--r--docs/html-intl/intl/zh-tw/preview/behavior-changes.jd402
-rw-r--r--docs/html-intl/intl/zh-tw/preview/features/runtime-permissions.jd794
-rw-r--r--docs/html-intl/intl/zh-tw/preview/overview.jd362
-rw-r--r--docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/index.jd72
-rw-r--r--docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/pausing.jd147
-rw-r--r--docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/recreating.jd178
-rw-r--r--docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/starting.jd285
-rw-r--r--docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/stopping.jd187
-rw-r--r--docs/html-intl/intl/zh-tw/training/basics/data-storage/databases.jd317
-rw-r--r--docs/html-intl/intl/zh-tw/training/basics/data-storage/files.jd379
-rw-r--r--docs/html-intl/intl/zh-tw/training/basics/data-storage/index.jd57
-rw-r--r--docs/html-intl/intl/zh-tw/training/basics/data-storage/shared-preferences.jd120
-rw-r--r--docs/html-intl/intl/zh-tw/training/basics/intents/filters.jd236
-rw-r--r--docs/html-intl/intl/zh-tw/training/basics/intents/index.jd62
-rw-r--r--docs/html-intl/intl/zh-tw/training/basics/intents/result.jd178
-rw-r--r--docs/html-intl/intl/zh-tw/training/basics/intents/sending.jd256
-rw-r--r--docs/html/design/design_toc.cs53
-rw-r--r--docs/html/guide/topics/resources/providing-resources.jd16
-rw-r--r--docs/html/guide/topics/security/permissions.jd4
-rw-r--r--docs/html/guide/topics/ui/actionbar.jd6
-rw-r--r--docs/html/images/tools/eclipse-notepad-pre-import--structure.pngbin0 -> 69767 bytes
-rw-r--r--docs/html/images/tools/studio-globe-icon.pngbin0 -> 710 bytes
-rw-r--r--docs/html/images/tools/studio-import-destination-dir.pngbin0 -> 35386 bytes
-rw-r--r--docs/html/images/tools/studio-import-options.pngbin0 -> 134373 bytes
-rw-r--r--docs/html/images/tools/studio-import-project-structure-android.pngbin0 -> 45592 bytes
-rw-r--r--docs/html/images/tools/studio-import-project-structure-project.pngbin0 -> 55738 bytes
-rw-r--r--docs/html/images/tools/studio-import-summary.pngbin0 -> 95295 bytes
-rw-r--r--docs/html/images/tools/studio-select-project-forimport.pngbin0 -> 46808 bytes
-rw-r--r--docs/html/images/tools/studio-setup-wizard.pngbin37815 -> 0 bytes
-rw-r--r--docs/html/preview/preview_toc.cs45
-rw-r--r--docs/html/sdk/installing/installing-adt.jd17
-rw-r--r--docs/html/sdk/installing/migrate.jd277
-rw-r--r--docs/html/sdk/installing/studio-tips.jd269
-rw-r--r--docs/html/tools/building/building-cmdline-ant.jd8
-rw-r--r--docs/html/tools/building/configuring-gradle.jd69
-rw-r--r--docs/html/tools/building/manifest-merge.jd510
-rw-r--r--docs/html/tools/help/adt.jd19
-rw-r--r--docs/html/tools/studio/eclipse-transition-guide.jd773
-rw-r--r--docs/html/tools/studio/index.jd323
-rw-r--r--docs/html/tools/studio/studio-config.jd174
-rw-r--r--docs/html/tools/studio/studio-features.jd123
-rw-r--r--docs/html/tools/tools_toc.cs26
-rw-r--r--docs/html/tools/workflow/index.jd14
-rw-r--r--docs/html/training/material/drawables.jd5
-rw-r--r--docs/html/training/safetynet/index.jd2
-rw-r--r--docs/html/training/training_toc.cs111
-rw-r--r--docs/html/training/volley/requestqueue.jd3
-rw-r--r--docs/html/training/wearables/watch-faces/drawing.jd27
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java16
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreSpi.java59
-rw-r--r--keystore/java/android/security/keystore/KeymasterUtils.java2
-rw-r--r--libs/hwui/Android.common.mk1
-rw-r--r--libs/hwui/DisplayListOp.h12
-rw-r--r--libs/hwui/OpenGLRenderer.cpp20
-rw-r--r--libs/hwui/Outline.h6
-rw-r--r--libs/hwui/Patch.cpp8
-rw-r--r--libs/hwui/Rect.h33
-rw-r--r--libs/hwui/RenderProperties.h2
-rw-r--r--libs/hwui/ShadowTessellator.cpp3
-rw-r--r--libs/hwui/SpotShadow.cpp35
-rw-r--r--libs/hwui/TextureCache.cpp2
-rw-r--r--libs/hwui/font/Font.cpp14
-rw-r--r--media/java/android/media/AudioManager.java26
-rw-r--r--media/java/android/media/MediaCodecInfo.java4
-rw-r--r--packages/DocumentsUI/res/values-af/strings.xml2
-rw-r--r--packages/DocumentsUI/res/values-bn-rBD/strings.xml2
-rw-r--r--packages/DocumentsUI/res/values-fr-rCA/strings.xml2
-rw-r--r--packages/DocumentsUI/res/values-pl/strings.xml2
-rw-r--r--packages/DocumentsUI/res/values-ta-rIN/strings.xml2
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java4
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java2
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java7
-rw-r--r--packages/SystemUI/AndroidManifest.xml4
-rw-r--r--packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml1
-rw-r--r--packages/SystemUI/res/layout/volume_dialog_row.xml2
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml4
-rw-r--r--packages/SystemUI/res/values-da/strings.xml2
-rw-r--r--packages/SystemUI/res/values-el/strings.xml4
-rw-r--r--packages/SystemUI/res/values-es/strings.xml12
-rw-r--r--packages/SystemUI/res/values-eu-rES/strings.xml2
-rw-r--r--packages/SystemUI/res/values-gl-rES/strings.xml2
-rw-r--r--packages/SystemUI/res/values-hy-rAM/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ka-rGE/strings.xml12
-rw-r--r--packages/SystemUI/res/values-kk-rKZ/strings.xml4
-rw-r--r--packages/SystemUI/res/values-ky-rKG/strings.xml12
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml12
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ms-rMY/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ne-rNP/strings.xml4
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ta-rIN/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ur-rPK/strings.xml12
-rw-r--r--packages/SystemUI/res/values-uz-rUZ/strings.xml12
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml12
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml12
-rw-r--r--packages/SystemUI/res/values/dimens.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistManager.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanel.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSTileView.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/ToggleSeekBar.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java52
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java8
-rw-r--r--rs/java/android/renderscript/ScriptGroup.java2
-rw-r--r--rs/java/android/renderscript/ScriptIntrinsicBLAS.java12
-rw-r--r--rs/jni/android_renderscript_RenderScript.cpp4
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java2
-rw-r--r--services/backup/java/com/android/server/backup/BackupManagerService.java78
-rw-r--r--services/core/java/com/android/server/AlarmManagerService.java6
-rw-r--r--services/core/java/com/android/server/AppOpsService.java45
-rw-r--r--services/core/java/com/android/server/BluetoothManagerService.java49
-rw-r--r--services/core/java/com/android/server/BluetoothService.java51
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java90
-rw-r--r--services/core/java/com/android/server/DeviceIdleController.java172
-rw-r--r--services/core/java/com/android/server/EventLogTags.logtags12
-rw-r--r--services/core/java/com/android/server/LockSettingsService.java13
-rw-r--r--services/core/java/com/android/server/MasterClearReceiver.java52
-rw-r--r--services/core/java/com/android/server/MountService.java188
-rw-r--r--services/core/java/com/android/server/TextServicesManagerService.java42
-rw-r--r--services/core/java/com/android/server/VibratorService.java82
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java279
-rw-r--r--services/core/java/com/android/server/accounts/TokenCache.java163
-rwxr-xr-xservices/core/java/com/android/server/am/ActiveServices.java32
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java58
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java135
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java12
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueue.java113
-rw-r--r--services/core/java/com/android/server/am/PendingIntentRecord.java3
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java2
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkMonitor.java84
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java2
-rw-r--r--services/core/java/com/android/server/content/ContentService.java53
-rw-r--r--services/core/java/com/android/server/dreams/DreamController.java13
-rw-r--r--services/core/java/com/android/server/fingerprint/FingerprintService.java30
-rw-r--r--services/core/java/com/android/server/location/GpsLocationProvider.java45
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java15
-rw-r--r--services/core/java/com/android/server/notification/NotificationDelegate.java2
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java4
-rw-r--r--services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java389
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java5
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java342
-rw-r--r--services/core/java/com/android/server/pm/PermissionsState.java18
-rw-r--r--services/core/java/com/android/server/pm/Settings.java154
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java4
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java82
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java7
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java4
-rw-r--r--services/core/java/com/android/server/telecom/TelecomLoaderService.java178
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java39
-rw-r--r--services/core/java/com/android/server/wm/AppTransition.java8
-rw-r--r--services/core/java/com/android/server/wm/Session.java8
-rw-r--r--services/core/java/com/android/server/wm/WindowAnimator.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java11
-rw-r--r--services/core/jni/com_android_server_am_BatteryStatsService.cpp73
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java66
-rw-r--r--services/java/com/android/server/SystemServer.java7
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java24
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java27
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java17
-rw-r--r--telecomm/java/android/telecom/Connection.java64
-rw-r--r--telecomm/java/android/telecom/ConnectionService.java6
-rw-r--r--telecomm/java/android/telecom/InCallService.java2
-rw-r--r--telecomm/java/android/telecom/PhoneAccount.java9
-rw-r--r--telecomm/java/android/telecom/RemoteConference.java69
-rw-r--r--telecomm/java/android/telecom/RemoteConnection.java5
-rw-r--r--telecomm/java/android/telecom/TelecomManager.java18
-rw-r--r--telephony/java/android/telephony/PhoneNumberUtils.java27
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java52
-rw-r--r--telephony/java/com/android/ims/ImsCallProfile.java10
-rw-r--r--telephony/java/com/android/internal/telephony/CellNetworkScanResult.java1
-rw-r--r--tests/ActivityTests/AndroidManifest.xml1
-rw-r--r--tests/Assist/src/com/android/test/assist/AssistInteractionSession.java24
-rw-r--r--tests/VoiceInteraction/res/layout/test_interaction.xml13
-rw-r--r--tests/VoiceInteraction/res/layout/voice_interaction_session.xml41
-rw-r--r--tests/VoiceInteraction/res/values/strings.xml3
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java103
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java3
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java133
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java42
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java2
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java10
-rw-r--r--wifi/java/android/net/wifi/ScanResult.java4
-rw-r--r--wifi/java/android/net/wifi/WifiConfiguration.java12
-rw-r--r--wifi/java/android/net/wifi/WifiInfo.java16
549 files changed, 49891 insertions, 3455 deletions
diff --git a/Android.mk b/Android.mk
index a02b326..e96a932 100644
--- a/Android.mk
+++ b/Android.mk
@@ -142,7 +142,6 @@ LOCAL_SRC_FILES += \
core/java/android/content/pm/IPackageManager.aidl \
core/java/android/content/pm/IPackageMoveObserver.aidl \
core/java/android/content/pm/IPackageStatsObserver.aidl \
- core/java/android/content/pm/IPackagesProvider.aidl \
core/java/android/content/pm/IOnPermissionsChangeListener.aidl \
core/java/android/database/IContentObserver.aidl \
core/java/android/hardware/ICameraService.aidl \
diff --git a/api/current.txt b/api/current.txt
index cd5c0a8..3304317 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10,10 +10,8 @@ package android {
field public static final java.lang.String ACCESS_COARSE_LOCATION = "android.permission.ACCESS_COARSE_LOCATION";
field public static final java.lang.String ACCESS_FINE_LOCATION = "android.permission.ACCESS_FINE_LOCATION";
field public static final java.lang.String ACCESS_LOCATION_EXTRA_COMMANDS = "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS";
- field public static final java.lang.String ACCESS_MOCK_LOCATION = "android.permission.ACCESS_MOCK_LOCATION";
field public static final java.lang.String ACCESS_NETWORK_STATE = "android.permission.ACCESS_NETWORK_STATE";
field public static final java.lang.String ACCESS_NOTIFICATION_POLICY = "android.permission.ACCESS_NOTIFICATION_POLICY";
- field public static final java.lang.String ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER";
field public static final java.lang.String ACCESS_WIFI_STATE = "android.permission.ACCESS_WIFI_STATE";
field public static final java.lang.String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER";
field public static final java.lang.String ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL";
@@ -42,7 +40,6 @@ package android {
field public static final java.lang.String BLUETOOTH_ADMIN = "android.permission.BLUETOOTH_ADMIN";
field public static final java.lang.String BLUETOOTH_PRIVILEGED = "android.permission.BLUETOOTH_PRIVILEGED";
field public static final java.lang.String BODY_SENSORS = "android.permission.BODY_SENSORS";
- field public static final java.lang.String BRICK = "android.permission.BRICK";
field public static final java.lang.String BROADCAST_PACKAGE_REMOVED = "android.permission.BROADCAST_PACKAGE_REMOVED";
field public static final java.lang.String BROADCAST_SMS = "android.permission.BROADCAST_SMS";
field public static final java.lang.String BROADCAST_STICKY = "android.permission.BROADCAST_STICKY";
@@ -59,33 +56,25 @@ package android {
field public static final java.lang.String CHANGE_WIFI_MULTICAST_STATE = "android.permission.CHANGE_WIFI_MULTICAST_STATE";
field public static final java.lang.String CHANGE_WIFI_STATE = "android.permission.CHANGE_WIFI_STATE";
field public static final java.lang.String CLEAR_APP_CACHE = "android.permission.CLEAR_APP_CACHE";
- field public static final java.lang.String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA";
field public static final java.lang.String CONTROL_LOCATION_UPDATES = "android.permission.CONTROL_LOCATION_UPDATES";
field public static final java.lang.String DELETE_CACHE_FILES = "android.permission.DELETE_CACHE_FILES";
field public static final java.lang.String DELETE_PACKAGES = "android.permission.DELETE_PACKAGES";
- field public static final java.lang.String DEVICE_POWER = "android.permission.DEVICE_POWER";
field public static final java.lang.String DIAGNOSTIC = "android.permission.DIAGNOSTIC";
field public static final java.lang.String DISABLE_KEYGUARD = "android.permission.DISABLE_KEYGUARD";
field public static final java.lang.String DUMP = "android.permission.DUMP";
field public static final java.lang.String EXPAND_STATUS_BAR = "android.permission.EXPAND_STATUS_BAR";
field public static final java.lang.String FACTORY_TEST = "android.permission.FACTORY_TEST";
field public static final java.lang.String FLASHLIGHT = "android.permission.FLASHLIGHT";
- field public static final java.lang.String FORCE_BACK = "android.permission.FORCE_BACK";
field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS";
- field public static final java.lang.String GET_TOP_ACTIVITY_INFO = "android.permission.GET_TOP_ACTIVITY_INFO";
field public static final java.lang.String GLOBAL_SEARCH = "android.permission.GLOBAL_SEARCH";
- field public static final java.lang.String HARDWARE_TEST = "android.permission.HARDWARE_TEST";
- field public static final java.lang.String INJECT_EVENTS = "android.permission.INJECT_EVENTS";
field public static final java.lang.String INSTALL_LOCATION_PROVIDER = "android.permission.INSTALL_LOCATION_PROVIDER";
field public static final java.lang.String INSTALL_PACKAGES = "android.permission.INSTALL_PACKAGES";
field public static final java.lang.String INSTALL_SHORTCUT = "com.android.launcher.permission.INSTALL_SHORTCUT";
- field public static final java.lang.String INTERNAL_SYSTEM_WINDOW = "android.permission.INTERNAL_SYSTEM_WINDOW";
field public static final java.lang.String INTERNET = "android.permission.INTERNET";
field public static final java.lang.String KILL_BACKGROUND_PROCESSES = "android.permission.KILL_BACKGROUND_PROCESSES";
field public static final java.lang.String LOCATION_HARDWARE = "android.permission.LOCATION_HARDWARE";
- field public static final java.lang.String MANAGE_APP_TOKENS = "android.permission.MANAGE_APP_TOKENS";
field public static final java.lang.String MANAGE_DOCUMENTS = "android.permission.MANAGE_DOCUMENTS";
field public static final java.lang.String MASTER_CLEAR = "android.permission.MASTER_CLEAR";
field public static final java.lang.String MEDIA_CONTENT_CONTROL = "android.permission.MEDIA_CONTENT_CONTROL";
@@ -120,13 +109,10 @@ package android {
field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
field public static final java.lang.String SEND_SMS = "android.permission.SEND_SMS";
- field public static final java.lang.String SET_ACTIVITY_WATCHER = "android.permission.SET_ACTIVITY_WATCHER";
field public static final java.lang.String SET_ALARM = "com.android.alarm.permission.SET_ALARM";
field public static final java.lang.String SET_ALWAYS_FINISH = "android.permission.SET_ALWAYS_FINISH";
field public static final java.lang.String SET_ANIMATION_SCALE = "android.permission.SET_ANIMATION_SCALE";
field public static final java.lang.String SET_DEBUG_APP = "android.permission.SET_DEBUG_APP";
- field public static final java.lang.String SET_ORIENTATION = "android.permission.SET_ORIENTATION";
- field public static final java.lang.String SET_POINTER_SPEED = "android.permission.SET_POINTER_SPEED";
field public static final deprecated java.lang.String SET_PREFERRED_APPLICATIONS = "android.permission.SET_PREFERRED_APPLICATIONS";
field public static final java.lang.String SET_PROCESS_LIMIT = "android.permission.SET_PROCESS_LIMIT";
field public static final java.lang.String SET_TIME = "android.permission.SET_TIME";
@@ -157,7 +143,6 @@ package android {
public static final class Manifest.permission_group {
ctor public Manifest.permission_group();
- field public static final java.lang.String ACCOUNTS = "android.permission-group.ACCOUNTS";
field public static final java.lang.String CALENDAR = "android.permission-group.CALENDAR";
field public static final java.lang.String CAMERA = "android.permission-group.CAMERA";
field public static final java.lang.String CONTACTS = "android.permission-group.CONTACTS";
@@ -3870,6 +3855,8 @@ package android.app {
method public void finishOp(java.lang.String, int, java.lang.String);
method public int noteOp(java.lang.String, int, java.lang.String);
method public int noteOpNoThrow(java.lang.String, int, java.lang.String);
+ method public int noteProxyOp(java.lang.String, java.lang.String);
+ method public int noteProxyOpNoThrow(java.lang.String, java.lang.String);
method public static java.lang.String permissionToOp(java.lang.String);
method public int startOp(java.lang.String, int, java.lang.String);
method public int startOpNoThrow(java.lang.String, int, java.lang.String);
@@ -3893,6 +3880,7 @@ package android.app {
field public static final java.lang.String OPSTR_READ_CALL_LOG = "android:read_call_log";
field public static final java.lang.String OPSTR_READ_CELL_BROADCASTS = "android:read_cell_broadcasts";
field public static final java.lang.String OPSTR_READ_CONTACTS = "android:read_contacts";
+ field public static final java.lang.String OPSTR_READ_EXTERNAL_STORAGE = "android:read_external_storage";
field public static final java.lang.String OPSTR_READ_PHONE_STATE = "android:read_phone_state";
field public static final java.lang.String OPSTR_READ_SMS = "android:read_sms";
field public static final java.lang.String OPSTR_RECEIVE_MMS = "android:receive_mms";
@@ -3905,6 +3893,7 @@ package android.app {
field public static final java.lang.String OPSTR_WRITE_CALENDAR = "android:write_calendar";
field public static final java.lang.String OPSTR_WRITE_CALL_LOG = "android:write_call_log";
field public static final java.lang.String OPSTR_WRITE_CONTACTS = "android:write_contacts";
+ field public static final java.lang.String OPSTR_WRITE_EXTERNAL_STORAGE = "android:write_external_storage";
}
public static abstract interface AppOpsManager.OnOpChangedListener {
@@ -5629,8 +5618,8 @@ package android.app.admin {
method public void clearDeviceOwnerApp(java.lang.String);
method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
- method public android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
- method public android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
+ method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
+ method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
method public void enableSystemApp(android.content.ComponentName, java.lang.String);
method public int enableSystemApp(android.content.ComponentName, android.content.Intent);
method public java.lang.String[] getAccountTypesWithManagementDisabled();
@@ -5778,7 +5767,6 @@ package android.app.admin {
field public static final int KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS = 8; // 0x8
field public static final int KEYGUARD_DISABLE_WIDGETS_ALL = 1; // 0x1
field public static final java.lang.String MIME_TYPE_PROVISIONING_NFC = "application/com.android.managedprovisioning";
- field public static final java.lang.String MIME_TYPE_PROVISIONING_NFC_V2 = "application/com.android.managedprovisioning.v2";
field public static final int PASSWORD_QUALITY_ALPHABETIC = 262144; // 0x40000
field public static final int PASSWORD_QUALITY_ALPHANUMERIC = 327680; // 0x50000
field public static final int PASSWORD_QUALITY_BIOMETRIC_WEAK = 32768; // 0x8000
@@ -5818,7 +5806,7 @@ package android.app.admin {
package android.app.assist {
- public deprecated class AssistContent implements android.os.Parcelable {
+ public class AssistContent implements android.os.Parcelable {
ctor public AssistContent();
method public int describeContents();
method public android.content.ClipData getClipData();
@@ -5846,10 +5834,12 @@ package android.app.assist {
}
public static class AssistStructure.ViewNode {
+ method public float getAlpha();
method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
method public int getChildCount();
method public java.lang.String getClassName();
method public java.lang.CharSequence getContentDescription();
+ method public float getElevation();
method public android.os.Bundle getExtras();
method public int getHeight();
method public java.lang.String getHint();
@@ -5868,6 +5858,7 @@ package android.app.assist {
method public float getTextSize();
method public int getTextStyle();
method public int getTop();
+ method public android.graphics.Matrix getTransformation();
method public int getVisibility();
method public int getWidth();
method public boolean isAccessibilityFocused();
@@ -9479,6 +9470,7 @@ package android.content.pm {
field public static final int PROTECTION_DANGEROUS = 1; // 0x1
field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40
field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20
+ field public static final int PROTECTION_FLAG_PRE23 = 128; // 0x80
field public static final int PROTECTION_FLAG_SYSTEM = 16; // 0x10
field public static final int PROTECTION_MASK_BASE = 15; // 0xf
field public static final int PROTECTION_MASK_FLAGS = 240; // 0xf0
@@ -18159,6 +18151,7 @@ package android.net {
method public deprecated void setNetworkPreference(int);
method public static deprecated boolean setProcessDefaultNetwork(android.net.Network);
method public void unregisterNetworkCallback(android.net.ConnectivityManager.NetworkCallback);
+ method public void unregisterNetworkCallback(android.app.PendingIntent);
field public static final deprecated java.lang.String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
field public static final java.lang.String ACTION_CAPTIVE_PORTAL_SIGN_IN = "android.net.conn.CAPTIVE_PORTAL";
field public static final java.lang.String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
@@ -19081,14 +19074,11 @@ package android.net.wifi {
field public static final int CHANNEL_WIDTH_40MHZ = 1; // 0x1
field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2
field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4
- field public static final long FLAG_80211mc_RESPONDER = 2L; // 0x2L
- field public static final long FLAG_PASSPOINT_NETWORK = 1L; // 0x1L
field public java.lang.String SSID;
field public java.lang.String capabilities;
field public int centerFreq0;
field public int centerFreq1;
field public int channelWidth;
- field public long flags;
field public int frequency;
field public int level;
field public java.lang.CharSequence operatorFriendlyName;
@@ -19136,7 +19126,7 @@ package android.net.wifi {
field public java.lang.String preSharedKey;
field public int priority;
field public java.lang.String providerFriendlyName;
- field public java.lang.Long[] roamingConsortiumIds;
+ field public long[] roamingConsortiumIds;
field public int status;
field public java.lang.String[] wepKeys;
field public int wepTxKeyIndex;
@@ -22711,7 +22701,7 @@ package android.os {
field public static final int KITKAT_WATCH = 20; // 0x14
field public static final int LOLLIPOP = 21; // 0x15
field public static final int LOLLIPOP_MR1 = 22; // 0x16
- field public static final int MNC = 10000; // 0x2710
+ field public static final int MNC = 23; // 0x17
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -22812,6 +22802,7 @@ package android.os {
public class DeadObjectException extends android.os.RemoteException {
ctor public DeadObjectException();
+ ctor public DeadObjectException(java.lang.String);
}
public final class Debug {
@@ -23653,7 +23644,7 @@ package android.os {
method public deprecated void setUserRestriction(java.lang.String, boolean);
method public deprecated void setUserRestrictions(android.os.Bundle);
method public deprecated void setUserRestrictions(android.os.Bundle, android.os.UserHandle);
- field public static final java.lang.String ALLOW_PARENT_APP_LINKING = "allow_parent_app_linking";
+ field public static final java.lang.String ALLOW_PARENT_PROFILE_APP_LINKING = "allow_parent_profile_app_linking";
field public static final java.lang.String DISALLOW_ADD_USER = "no_add_user";
field public static final java.lang.String DISALLOW_ADJUST_VOLUME = "no_adjust_volume";
field public static final java.lang.String DISALLOW_APPS_CONTROL = "no_control_apps";
@@ -26435,6 +26426,7 @@ package android.provider {
field public static final java.lang.String ACTION_LOCATION_SOURCE_SETTINGS = "android.settings.LOCATION_SOURCE_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS";
+ field public static final java.lang.String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.MANAGE_OVERLAY_PERMISSION";
field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS";
field public static final java.lang.String ACTION_NETWORK_OPERATOR_SETTINGS = "android.settings.NETWORK_OPERATOR_SETTINGS";
field public static final java.lang.String ACTION_NFCSHARING_SETTINGS = "android.settings.NFCSHARING_SETTINGS";
@@ -28815,6 +28807,7 @@ package android.service.voice {
public class VoiceInteractionSession implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback {
ctor public VoiceInteractionSession(android.content.Context);
ctor public VoiceInteractionSession(android.content.Context, android.os.Handler);
+ method public void closeSystemDialogs();
method public void finish();
method public android.content.Context getContext();
method public android.view.LayoutInflater getLayoutInflater();
@@ -30462,7 +30455,7 @@ package android.telecom {
method public void unregisterPhoneAccount(android.telecom.PhoneAccountHandle);
field public static final java.lang.String ACTION_CHANGE_DEFAULT_DIALER = "android.telecom.action.CHANGE_DEFAULT_DIALER";
field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
- field public static final java.lang.String ACTION_CONNECTION_SERVICE_CONFIGURE = "android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
+ field public static final java.lang.String ACTION_CONFIGURE_PHONE_ACCOUNT = "android.telecom.action.CONFIGURE_PHONE_ACCOUNT";
field public static final java.lang.String ACTION_DEFAULT_DIALER_CHANGED = "android.telecom.action.DEFAULT_DIALER_CHANGED";
field public static final java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
field public static final java.lang.String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
@@ -31091,7 +31084,7 @@ package android.telephony {
method public java.lang.String getLine1Number();
method public java.lang.String getMmsUAProfUrl();
method public java.lang.String getMmsUserAgent();
- method public java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
+ method public deprecated java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
method public java.lang.String getNetworkCountryIso();
method public java.lang.String getNetworkOperator();
method public java.lang.String getNetworkOperatorName();
@@ -36962,6 +36955,7 @@ package android.view {
method public abstract android.view.ViewStructure newChild(int);
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
+ method public abstract void setAlpha(float);
method public abstract void setCheckable(boolean);
method public abstract void setChecked(boolean);
method public abstract void setChildCount(int);
@@ -36970,6 +36964,7 @@ package android.view {
method public abstract void setContentDescription(java.lang.CharSequence);
method public abstract void setContextClickable(boolean);
method public abstract void setDimens(int, int, int, int, int, int);
+ method public abstract void setElevation(float);
method public abstract void setEnabled(boolean);
method public abstract void setFocusable(boolean);
method public abstract void setFocused(boolean);
@@ -36980,6 +36975,7 @@ package android.view {
method public abstract void setText(java.lang.CharSequence);
method public abstract void setText(java.lang.CharSequence, int, int);
method public abstract void setTextStyle(float, int, int, int);
+ method public abstract void setTransformation(android.graphics.Matrix);
method public abstract void setVisibility(int);
}
@@ -37472,6 +37468,7 @@ package android.view.accessibility {
field public static final deprecated int MAX_TEXT_LENGTH = 500; // 0x1f4
field public static final int TYPES_ALL_MASK = -1; // 0xffffffff
field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000
+ field public static final int TYPE_ASSIST_READING_CONTEXT = 16777216; // 0x1000000
field public static final int TYPE_GESTURE_DETECTION_END = 524288; // 0x80000
field public static final int TYPE_GESTURE_DETECTION_START = 262144; // 0x40000
field public static final int TYPE_NOTIFICATION_STATE_CHANGED = 64; // 0x40
diff --git a/api/system-current.txt b/api/system-current.txt
index 574f0c8..e3f003c 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -232,7 +232,6 @@ package android {
public static final class Manifest.permission_group {
ctor public Manifest.permission_group();
- field public static final java.lang.String ACCOUNTS = "android.permission-group.ACCOUNTS";
field public static final java.lang.String CALENDAR = "android.permission-group.CALENDAR";
field public static final java.lang.String CAMERA = "android.permission-group.CAMERA";
field public static final java.lang.String CONTACTS = "android.permission-group.CONTACTS";
@@ -3965,6 +3964,8 @@ package android.app {
method public void finishOp(java.lang.String, int, java.lang.String);
method public int noteOp(java.lang.String, int, java.lang.String);
method public int noteOpNoThrow(java.lang.String, int, java.lang.String);
+ method public int noteProxyOp(java.lang.String, java.lang.String);
+ method public int noteProxyOpNoThrow(java.lang.String, java.lang.String);
method public static java.lang.String permissionToOp(java.lang.String);
method public int startOp(java.lang.String, int, java.lang.String);
method public int startOpNoThrow(java.lang.String, int, java.lang.String);
@@ -3989,6 +3990,7 @@ package android.app {
field public static final java.lang.String OPSTR_READ_CALL_LOG = "android:read_call_log";
field public static final java.lang.String OPSTR_READ_CELL_BROADCASTS = "android:read_cell_broadcasts";
field public static final java.lang.String OPSTR_READ_CONTACTS = "android:read_contacts";
+ field public static final java.lang.String OPSTR_READ_EXTERNAL_STORAGE = "android:read_external_storage";
field public static final java.lang.String OPSTR_READ_PHONE_STATE = "android:read_phone_state";
field public static final java.lang.String OPSTR_READ_SMS = "android:read_sms";
field public static final java.lang.String OPSTR_RECEIVE_MMS = "android:receive_mms";
@@ -4001,6 +4003,7 @@ package android.app {
field public static final java.lang.String OPSTR_WRITE_CALENDAR = "android:write_calendar";
field public static final java.lang.String OPSTR_WRITE_CALL_LOG = "android:write_call_log";
field public static final java.lang.String OPSTR_WRITE_CONTACTS = "android:write_contacts";
+ field public static final java.lang.String OPSTR_WRITE_EXTERNAL_STORAGE = "android:write_external_storage";
}
public static abstract interface AppOpsManager.OnOpChangedListener {
@@ -5736,8 +5739,8 @@ package android.app.admin {
method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
method public void clearProfileOwner(android.content.ComponentName);
method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
- method public android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
- method public android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
+ method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
+ method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
method public void enableSystemApp(android.content.ComponentName, java.lang.String);
method public int enableSystemApp(android.content.ComponentName, android.content.Intent);
method public java.lang.String[] getAccountTypesWithManagementDisabled();
@@ -5896,7 +5899,6 @@ package android.app.admin {
field public static final int KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS = 8; // 0x8
field public static final int KEYGUARD_DISABLE_WIDGETS_ALL = 1; // 0x1
field public static final java.lang.String MIME_TYPE_PROVISIONING_NFC = "application/com.android.managedprovisioning";
- field public static final java.lang.String MIME_TYPE_PROVISIONING_NFC_V2 = "application/com.android.managedprovisioning.v2";
field public static final int PASSWORD_QUALITY_ALPHABETIC = 262144; // 0x40000
field public static final int PASSWORD_QUALITY_ALPHANUMERIC = 327680; // 0x50000
field public static final int PASSWORD_QUALITY_BIOMETRIC_WEAK = 32768; // 0x8000
@@ -5936,7 +5938,7 @@ package android.app.admin {
package android.app.assist {
- public deprecated class AssistContent implements android.os.Parcelable {
+ public class AssistContent implements android.os.Parcelable {
ctor public AssistContent();
method public int describeContents();
method public android.content.ClipData getClipData();
@@ -5964,10 +5966,12 @@ package android.app.assist {
}
public static class AssistStructure.ViewNode {
+ method public float getAlpha();
method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
method public int getChildCount();
method public java.lang.String getClassName();
method public java.lang.CharSequence getContentDescription();
+ method public float getElevation();
method public android.os.Bundle getExtras();
method public int getHeight();
method public java.lang.String getHint();
@@ -5986,6 +5990,7 @@ package android.app.assist {
method public float getTextSize();
method public int getTextStyle();
method public int getTop();
+ method public android.graphics.Matrix getTransformation();
method public int getVisibility();
method public int getWidth();
method public boolean isAccessibilityFocused();
@@ -9805,6 +9810,7 @@ package android.content.pm {
field public static final int PROTECTION_DANGEROUS = 1; // 0x1
field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40
field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20
+ field public static final int PROTECTION_FLAG_PRE23 = 128; // 0x80
field public static final int PROTECTION_FLAG_SYSTEM = 16; // 0x10
field public static final int PROTECTION_MASK_BASE = 15; // 0xf
field public static final int PROTECTION_MASK_FLAGS = 240; // 0xf0
@@ -13418,7 +13424,6 @@ package android.hardware {
public abstract class SensorManager {
method public boolean cancelTriggerSensor(android.hardware.TriggerEventListener, android.hardware.Sensor);
- method public boolean enableDataInjectionMode(boolean);
method public boolean flush(android.hardware.SensorEventListener);
method public static float getAltitude(float, float);
method public static void getAngleChange(float[], float[], float[]);
@@ -13431,6 +13436,7 @@ package android.hardware {
method public static void getRotationMatrixFromVector(float[], float[]);
method public java.util.List<android.hardware.Sensor> getSensorList(int);
method public deprecated int getSensors();
+ method public boolean initDataInjection(boolean);
method public boolean injectSensorData(android.hardware.Sensor, float[], int, long);
method public deprecated boolean registerListener(android.hardware.SensorListener, int);
method public deprecated boolean registerListener(android.hardware.SensorListener, int, int);
@@ -19660,6 +19666,7 @@ package android.net {
method public deprecated void setNetworkPreference(int);
method public static deprecated boolean setProcessDefaultNetwork(android.net.Network);
method public void unregisterNetworkCallback(android.net.ConnectivityManager.NetworkCallback);
+ method public void unregisterNetworkCallback(android.app.PendingIntent);
field public static final deprecated java.lang.String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
field public static final java.lang.String ACTION_CAPTIVE_PORTAL_SIGN_IN = "android.net.conn.CAPTIVE_PORTAL";
field public static final java.lang.String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
@@ -20823,14 +20830,11 @@ package android.net.wifi {
field public static final int CHANNEL_WIDTH_40MHZ = 1; // 0x1
field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2
field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4
- field public static final long FLAG_80211mc_RESPONDER = 2L; // 0x2L
- field public static final long FLAG_PASSPOINT_NETWORK = 1L; // 0x1L
field public java.lang.String SSID;
field public java.lang.String capabilities;
field public int centerFreq0;
field public int centerFreq1;
field public int channelWidth;
- field public long flags;
field public int frequency;
field public int level;
field public java.lang.CharSequence operatorFriendlyName;
@@ -20885,7 +20889,7 @@ package android.net.wifi {
field public java.lang.String preSharedKey;
field public int priority;
field public java.lang.String providerFriendlyName;
- field public java.lang.Long[] roamingConsortiumIds;
+ field public long[] roamingConsortiumIds;
field public int status;
field public java.lang.String[] wepKeys;
field public int wepTxKeyIndex;
@@ -24644,7 +24648,7 @@ package android.os {
field public static final int KITKAT_WATCH = 20; // 0x14
field public static final int LOLLIPOP = 21; // 0x15
field public static final int LOLLIPOP_MR1 = 22; // 0x16
- field public static final int MNC = 10000; // 0x2710
+ field public static final int MNC = 23; // 0x17
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -24745,6 +24749,7 @@ package android.os {
public class DeadObjectException extends android.os.RemoteException {
ctor public DeadObjectException();
+ ctor public DeadObjectException(java.lang.String);
}
public final class Debug {
@@ -25598,7 +25603,7 @@ package android.os {
method public deprecated void setUserRestriction(java.lang.String, boolean);
method public deprecated void setUserRestrictions(android.os.Bundle);
method public deprecated void setUserRestrictions(android.os.Bundle, android.os.UserHandle);
- field public static final java.lang.String ALLOW_PARENT_APP_LINKING = "allow_parent_app_linking";
+ field public static final java.lang.String ALLOW_PARENT_PROFILE_APP_LINKING = "allow_parent_profile_app_linking";
field public static final java.lang.String DISALLOW_ADD_USER = "no_add_user";
field public static final java.lang.String DISALLOW_ADJUST_VOLUME = "no_adjust_volume";
field public static final java.lang.String DISALLOW_APPS_CONTROL = "no_control_apps";
@@ -28482,6 +28487,7 @@ package android.provider {
field public static final java.lang.String ACTION_LOCATION_SOURCE_SETTINGS = "android.settings.LOCATION_SOURCE_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS";
+ field public static final java.lang.String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.MANAGE_OVERLAY_PERMISSION";
field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS";
field public static final java.lang.String ACTION_NETWORK_OPERATOR_SETTINGS = "android.settings.NETWORK_OPERATOR_SETTINGS";
field public static final java.lang.String ACTION_NFCSHARING_SETTINGS = "android.settings.NFCSHARING_SETTINGS";
@@ -30955,6 +30961,7 @@ package android.service.voice {
public class VoiceInteractionSession implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback {
ctor public VoiceInteractionSession(android.content.Context);
ctor public VoiceInteractionSession(android.content.Context, android.os.Handler);
+ method public void closeSystemDialogs();
method public void finish();
method public android.content.Context getContext();
method public android.view.LayoutInflater getLayoutInflater();
@@ -32681,7 +32688,7 @@ package android.telecom {
method public void unregisterPhoneAccount(android.telecom.PhoneAccountHandle);
field public static final java.lang.String ACTION_CHANGE_DEFAULT_DIALER = "android.telecom.action.CHANGE_DEFAULT_DIALER";
field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
- field public static final java.lang.String ACTION_CONNECTION_SERVICE_CONFIGURE = "android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
+ field public static final java.lang.String ACTION_CONFIGURE_PHONE_ACCOUNT = "android.telecom.action.CONFIGURE_PHONE_ACCOUNT";
field public static final java.lang.String ACTION_DEFAULT_DIALER_CHANGED = "android.telecom.action.DEFAULT_DIALER_CHANGED";
field public static final java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
field public static final java.lang.String ACTION_PHONE_ACCOUNT_REGISTERED = "android.telecom.action.PHONE_ACCOUNT_REGISTERED";
@@ -33333,7 +33340,7 @@ package android.telephony {
method public java.lang.String getLine1Number();
method public java.lang.String getMmsUAProfUrl();
method public java.lang.String getMmsUserAgent();
- method public java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
+ method public deprecated java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
method public java.lang.String getNetworkCountryIso();
method public java.lang.String getNetworkOperator();
method public java.lang.String getNetworkOperatorName();
@@ -39243,6 +39250,7 @@ package android.view {
method public abstract android.view.ViewStructure newChild(int);
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
+ method public abstract void setAlpha(float);
method public abstract void setCheckable(boolean);
method public abstract void setChecked(boolean);
method public abstract void setChildCount(int);
@@ -39251,6 +39259,7 @@ package android.view {
method public abstract void setContentDescription(java.lang.CharSequence);
method public abstract void setContextClickable(boolean);
method public abstract void setDimens(int, int, int, int, int, int);
+ method public abstract void setElevation(float);
method public abstract void setEnabled(boolean);
method public abstract void setFocusable(boolean);
method public abstract void setFocused(boolean);
@@ -39261,6 +39270,7 @@ package android.view {
method public abstract void setText(java.lang.CharSequence);
method public abstract void setText(java.lang.CharSequence, int, int);
method public abstract void setTextStyle(float, int, int, int);
+ method public abstract void setTransformation(android.graphics.Matrix);
method public abstract void setVisibility(int);
}
@@ -39756,6 +39766,7 @@ package android.view.accessibility {
field public static final deprecated int MAX_TEXT_LENGTH = 500; // 0x1f4
field public static final int TYPES_ALL_MASK = -1; // 0xffffffff
field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000
+ field public static final int TYPE_ASSIST_READING_CONTEXT = 16777216; // 0x1000000
field public static final int TYPE_GESTURE_DETECTION_END = 524288; // 0x80000
field public static final int TYPE_GESTURE_DETECTION_START = 262144; // 0x40000
field public static final int TYPE_NOTIFICATION_STATE_CHANGED = 64; // 0x40
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 13fda59..ca6c6ca 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -767,7 +767,7 @@ public class Am extends BaseCommand {
return;
}
System.out.println("Starting service: " + intent);
- ComponentName cn = mAm.startService(null, intent, intent.getType(), mUserId);
+ ComponentName cn = mAm.startService(null, intent, intent.getType(), null, mUserId);
if (cn == null) {
System.err.println("Error: Not found; no service started.");
} else if (cn.getPackageName().equals("!")) {
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 2be44bc..ce83caa 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -204,6 +204,10 @@ public final class Pm {
return runGrantRevokePermission(false);
}
+ if ("reset-permissions".equals(op)) {
+ return runResetPermissions();
+ }
+
if ("set-permission-enforced".equals(op)) {
return runSetPermissionEnforced();
}
@@ -1636,6 +1640,24 @@ public final class Pm {
}
}
+ private int runResetPermissions() {
+ try {
+ mPm.resetRuntimePermissions();
+ return 0;
+ } catch (RemoteException e) {
+ System.err.println(e.toString());
+ System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
+ } catch (IllegalArgumentException e) {
+ System.err.println("Bad argument: " + e.toString());
+ showUsage();
+ return 1;
+ } catch (SecurityException e) {
+ System.err.println("Operation not allowed: " + e.toString());
+ return 1;
+ }
+ }
+
private int runSetPermissionEnforced() {
final String permission = nextArg();
if (permission == null) {
@@ -1911,6 +1933,7 @@ public final class Pm {
System.err.println(" pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
System.err.println(" pm grant [--user USER_ID] PACKAGE PERMISSION");
System.err.println(" pm revoke [--user USER_ID] PACKAGE PERMISSION");
+ System.err.println(" pm reset-permissions");
System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]");
System.err.println(" pm get-install-location");
System.err.println(" pm set-permission-enforced PERMISSION [true|false]");
@@ -1988,6 +2011,8 @@ public final class Pm {
System.err.println(" manifest, be runtime permissions (protection level dangerous),");
System.err.println(" and the app targeting SDK greater than Lollipop MR1.");
System.err.println("");
+ System.err.println("pm reset-permissions: revert all runtime permissions to their default state.");
+ System.err.println("");
System.err.println("pm get-install-location: returns the current install location.");
System.err.println(" 0 [auto]: Let system decide the best location");
System.err.println(" 1 [internal]: Install on internal device storage");
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 3001c2c..aa7692b 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -489,7 +489,8 @@ public class AccountManager {
* <p>It is safe to call this method from the main thread.
*
* <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#GET_ACCOUNTS}.
+ * {@link android.Manifest.permission#GET_ACCOUNTS} or share a uid with the
+ * authenticator that owns the account type.
*
* @param type The type of accounts to return, null to retrieve all accounts
* @return An array of {@link Account}, one per matching account. Empty
@@ -615,7 +616,8 @@ public class AccountManager {
* {@link AccountManagerFuture} must not be used on the main thread.
*
* <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#GET_ACCOUNTS}.
+ * {@link android.Manifest.permission#GET_ACCOUNTS} or share a uid with the
+ * authenticator that owns the account type.
*
* @param type The type of accounts to return, must not be null
* @param features An array of the account features to require,
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index e8ab109..9c2e208 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -6473,20 +6473,22 @@ public class Activity extends ContextThemeWrapper
}
private void dispatchRequestPermissionsResult(int requestCode, Intent data) {
- String[] permissions = data.getStringArrayExtra(
- PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES);
- final int[] grantResults = data.getIntArrayExtra(
- PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS);
+ // If the package installer crashed we may have not data - best effort.
+ String[] permissions = (data != null) ? data.getStringArrayExtra(
+ PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES) : new String[0];
+ final int[] grantResults = (data != null) ? data.getIntArrayExtra(
+ PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS) : new int[0];
onRequestPermissionsResult(requestCode, permissions, grantResults);
}
private void dispatchRequestPermissionsResultToFragment(int requestCode, Intent data,
- Fragment fragement) {
- String[] permissions = data.getStringArrayExtra(
- PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES);
- final int[] grantResults = data.getIntArrayExtra(
- PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS);
- fragement.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ Fragment fragment) {
+ // If the package installer crashed we may have not data - best effort.
+ String[] permissions = (data != null) ? data.getStringArrayExtra(
+ PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES) : new String[0];
+ final int[] grantResults = (data != null) ? data.getIntArrayExtra(
+ PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS) : new int[0];
+ fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
class HostCallbacks extends FragmentHostCallback<Activity> {
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 3035e3d..cc93ac9 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -921,8 +921,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
IApplicationThread app = ApplicationThreadNative.asInterface(b);
Intent service = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
+ String callingPackage = data.readString();
int userId = data.readInt();
- ComponentName cn = startService(app, service, resolvedType, userId);
+ ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);
reply.writeNoException();
ComponentName.writeToParcel(cn, reply);
return true;
@@ -976,9 +977,11 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
String resolvedType = data.readString();
b = data.readStrongBinder();
int fl = data.readInt();
+ String callingPackage = data.readString();
int userId = data.readInt();
IServiceConnection conn = IServiceConnection.Stub.asInterface(b);
- int res = bindService(app, token, service, resolvedType, conn, fl, userId);
+ int res = bindService(app, token, service, resolvedType, conn, fl,
+ callingPackage, userId);
reply.writeNoException();
reply.writeInt(res);
return true;
@@ -1568,7 +1571,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
data.enforceInterface(IActivityManager.descriptor);
Intent service = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
- IBinder binder = peekService(service, resolvedType);
+ String callingPackage = data.readString();
+ IBinder binder = peekService(service, resolvedType, callingPackage);
reply.writeNoException();
reply.writeStrongBinder(binder);
return true;
@@ -2217,6 +2221,14 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return true;
}
+ case IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ boolean res = isScreenCaptureAllowedOnCurrentActivity();
+ reply.writeNoException();
+ reply.writeInt(res ? 1 : 0);
+ return true;
+ }
+
case KILL_UID_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
int uid = data.readInt();
@@ -3630,7 +3642,7 @@ class ActivityManagerProxy implements IActivityManager
}
public ComponentName startService(IApplicationThread caller, Intent service,
- String resolvedType, int userId) throws RemoteException
+ String resolvedType, String callingPackage, int userId) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -3638,6 +3650,7 @@ class ActivityManagerProxy implements IActivityManager
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
service.writeToParcel(data, 0);
data.writeString(resolvedType);
+ data.writeString(callingPackage);
data.writeInt(userId);
mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
@@ -3700,7 +3713,7 @@ class ActivityManagerProxy implements IActivityManager
}
public int bindService(IApplicationThread caller, IBinder token,
Intent service, String resolvedType, IServiceConnection connection,
- int flags, int userId) throws RemoteException {
+ int flags, String callingPackage, int userId) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
@@ -3710,6 +3723,7 @@ class ActivityManagerProxy implements IActivityManager
data.writeString(resolvedType);
data.writeStrongBinder(connection.asBinder());
data.writeInt(flags);
+ data.writeString(callingPackage);
data.writeInt(userId);
mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
@@ -3775,12 +3789,14 @@ class ActivityManagerProxy implements IActivityManager
reply.recycle();
}
- public IBinder peekService(Intent service, String resolvedType) throws RemoteException {
+ public IBinder peekService(Intent service, String resolvedType, String callingPackage)
+ throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
service.writeToParcel(data, 0);
data.writeString(resolvedType);
+ data.writeString(callingPackage);
mRemote.transact(PEEK_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
IBinder binder = reply.readStrongBinder();
@@ -5409,6 +5425,18 @@ class ActivityManagerProxy implements IActivityManager
return res;
}
+ public boolean isScreenCaptureAllowedOnCurrentActivity() throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ mRemote.transact(IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION, data, reply, 0);
+ reply.readException();
+ boolean res = reply.readInt() != 0;
+ data.recycle();
+ reply.recycle();
+ return res;
+ }
+
public void killUid(int uid, String reason) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 8a61ec6..bf3bfae 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -229,8 +229,12 @@ public class AppOpsManager {
public static final int OP_READ_CELL_BROADCASTS = 57;
/** @hide Inject mock location into the system. */
public static final int OP_MOCK_LOCATION = 58;
+ /** @hide Read external storage. */
+ public static final int OP_READ_EXTERNAL_STORAGE = 59;
+ /** @hide Write external storage. */
+ public static final int OP_WRITE_EXTERNAL_STORAGE = 60;
/** @hide */
- public static final int _NUM_OP = 59;
+ public static final int _NUM_OP = 61;
/** Access to coarse location information. */
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -313,6 +317,12 @@ public class AppOpsManager {
/** Inject mock location into the system. */
public static final String OPSTR_MOCK_LOCATION
= "android:mock_location";
+ /** Read external storage. */
+ public static final String OPSTR_READ_EXTERNAL_STORAGE
+ = "android:read_external_storage";
+ /** Write external storage. */
+ public static final String OPSTR_WRITE_EXTERNAL_STORAGE
+ = "android:write_external_storage";
/**
* This maps each operation to the operation that serves as the
@@ -381,7 +391,9 @@ public class AppOpsManager {
OP_USE_FINGERPRINT,
OP_BODY_SENSORS,
OP_READ_CELL_BROADCASTS,
- OP_MOCK_LOCATION
+ OP_MOCK_LOCATION,
+ OP_READ_EXTERNAL_STORAGE,
+ OP_WRITE_EXTERNAL_STORAGE
};
/**
@@ -447,7 +459,9 @@ public class AppOpsManager {
OPSTR_USE_FINGERPRINT,
OPSTR_BODY_SENSORS,
OPSTR_READ_CELL_BROADCASTS,
- OPSTR_MOCK_LOCATION
+ OPSTR_MOCK_LOCATION,
+ OPSTR_READ_EXTERNAL_STORAGE,
+ OPSTR_WRITE_EXTERNAL_STORAGE
};
/**
@@ -513,7 +527,9 @@ public class AppOpsManager {
"USE_FINGERPRINT",
"BODY_SENSORS",
"READ_CELL_BROADCASTS",
- "MOCK_LOCATION"
+ "MOCK_LOCATION",
+ "OPSTR_READ_EXTERNAL_STORAGE",
+ "OPSTR_WRITE_EXTERNAL_STORAGE",
};
/**
@@ -579,7 +595,9 @@ public class AppOpsManager {
Manifest.permission.USE_FINGERPRINT,
Manifest.permission.BODY_SENSORS,
Manifest.permission.READ_CELL_BROADCASTS,
- null
+ null,
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.WRITE_EXTERNAL_STORAGE,
};
/**
@@ -646,7 +664,9 @@ public class AppOpsManager {
null, // USE_FINGERPRINT
null, // BODY_SENSORS
null, // READ_CELL_BROADCASTS
- null // MOCK_LOCATION
+ null, // MOCK_LOCATION
+ null, // READ_EXTERNAL_STORAGE
+ null // WRITE_EXTERNAL_STORAGE
};
/**
@@ -712,7 +732,9 @@ public class AppOpsManager {
false, // USE_FINGERPRINT
false, // BODY_SENSORS
false, // READ_CELL_BROADCASTS
- false // MOCK_LOCATION
+ false, // MOCK_LOCATION
+ false, // READ_EXTERNAL_STORAGE
+ false // WRITE_EXTERNAL_STORAGE
};
/**
@@ -777,7 +799,9 @@ public class AppOpsManager {
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ALLOWED,
- AppOpsManager.MODE_ERRORED // OP_MOCK_LOCATION
+ AppOpsManager.MODE_ERRORED, // OP_MOCK_LOCATION
+ AppOpsManager.MODE_ALLOWED,
+ AppOpsManager.MODE_ALLOWED
};
/**
@@ -846,6 +870,8 @@ public class AppOpsManager {
false,
false,
false,
+ false,
+ false,
false
};
@@ -1056,13 +1082,18 @@ public class AppOpsManager {
private final long mTime;
private final long mRejectTime;
private final int mDuration;
+ private final int mProxyUid;
+ private final String mProxyPackageName;
- public OpEntry(int op, int mode, long time, long rejectTime, int duration) {
+ public OpEntry(int op, int mode, long time, long rejectTime, int duration,
+ int proxyUid, String proxyPackage) {
mOp = op;
mMode = mode;
mTime = time;
mRejectTime = rejectTime;
mDuration = duration;
+ mProxyUid = proxyUid;
+ mProxyPackageName = proxyPackage;
}
public int getOp() {
@@ -1089,6 +1120,14 @@ public class AppOpsManager {
return mDuration == -1 ? (int)(System.currentTimeMillis()-mTime) : mDuration;
}
+ public int getProxyUid() {
+ return mProxyUid;
+ }
+
+ public String getProxyPackageName() {
+ return mProxyPackageName;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -1101,6 +1140,8 @@ public class AppOpsManager {
dest.writeLong(mTime);
dest.writeLong(mRejectTime);
dest.writeInt(mDuration);
+ dest.writeInt(mProxyUid);
+ dest.writeString(mProxyPackageName);
}
OpEntry(Parcel source) {
@@ -1109,6 +1150,8 @@ public class AppOpsManager {
mTime = source.readLong();
mRejectTime = source.readLong();
mDuration = source.readInt();
+ mProxyUid = source.readInt();
+ mProxyPackageName = source.readString();
}
public static final Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
@@ -1353,6 +1396,33 @@ public class AppOpsManager {
}
/**
+ * Make note of an application performing an operation on behalf of another
+ * application when handling an IPC. Note that you must pass the package name
+ * of the application that is being proxied while its UID will be inferred from
+ * the IPC state; this function will verify that the calling uid and proxied
+ * package name match, and if not, return {@link #MODE_IGNORED}. If this call
+ * succeeds, the last execution time of the operation for the proxied app and
+ * your app will be updated to the current time.
+ * @param op The operation to note. One of the OPSTR_* constants.
+ * @param proxiedPackageName The name of the application calling into the proxy application.
+ * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
+ * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
+ * causing the app to crash).
+ * @throws SecurityException If the app has been configured to crash on this op.
+ */
+ public int noteProxyOp(String op, String proxiedPackageName) {
+ return noteProxyOp(strOpToOp(op), proxiedPackageName);
+ }
+
+ /**
+ * Like {@link #noteProxyOp(String, String)} but instead
+ * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
+ */
+ public int noteProxyOpNoThrow(String op, String proxiedPackageName) {
+ return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName);
+ }
+
+ /**
* Report that an application has started executing a long-running operation. Note that you
* must pass in both the uid and name of the application to be checked; this function will
* verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
@@ -1429,7 +1499,7 @@ public class AppOpsManager {
return mService.checkOperation(op, uid, packageName);
} catch (RemoteException e) {
}
- return MODE_IGNORED;
+ return MODE_ERRORED;
}
/**
@@ -1475,7 +1545,7 @@ public class AppOpsManager {
return mService.checkAudioOperation(op, stream, uid, packageName);
} catch (RemoteException e) {
}
- return MODE_IGNORED;
+ return MODE_ERRORED;
}
/**
@@ -1506,6 +1576,49 @@ public class AppOpsManager {
}
/**
+ * Make note of an application performing an operation on behalf of another
+ * application when handling an IPC. Note that you must pass the package name
+ * of the application that is being proxied while its UID will be inferred from
+ * the IPC state; this function will verify that the calling uid and proxied
+ * package name match, and if not, return {@link #MODE_IGNORED}. If this call
+ * succeeds, the last execution time of the operation for the proxied app and
+ * your app will be updated to the current time.
+ * @param op The operation to note. One of the OPSTR_* constants.
+ * @param proxiedPackageName The name of the application calling into the proxy application.
+ * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
+ * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
+ * causing the app to crash).
+ * @throws SecurityException If the proxy or proxied app has been configured to
+ * crash on this op.
+ *
+ * @hide
+ */
+ public int noteProxyOp(int op, String proxiedPackageName) {
+ int mode = noteProxyOpNoThrow(op, proxiedPackageName);
+ if (mode == MODE_ERRORED) {
+ throw new SecurityException("Proxy package " + mContext.getOpPackageName()
+ + " from uid " + Process.myUid() + " or calling package "
+ + proxiedPackageName + " from uid " + Binder.getCallingUid()
+ + " not allowed to perform " + sOpNames[op]);
+ }
+ return mode;
+ }
+
+ /**
+ * Like {@link #noteProxyOp(int, String)} but instead
+ * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
+ * @hide
+ */
+ public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
+ try {
+ return mService.noteProxyOperation(op, mContext.getOpPackageName(),
+ Binder.getCallingUid(), proxiedPackageName);
+ } catch (RemoteException e) {
+ }
+ return MODE_ERRORED;
+ }
+
+ /**
* Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
* returns {@link #MODE_ERRORED}.
* @hide
@@ -1515,7 +1628,7 @@ public class AppOpsManager {
return mService.noteOperation(op, uid, packageName);
} catch (RemoteException e) {
}
- return MODE_IGNORED;
+ return MODE_ERRORED;
}
/** @hide */
@@ -1577,7 +1690,7 @@ public class AppOpsManager {
return mService.startOperation(getToken(mService), op, uid, packageName);
} catch (RemoteException e) {
}
- return MODE_IGNORED;
+ return MODE_ERRORED;
}
/** @hide */
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 903411e..13030ca 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -717,6 +717,7 @@ final class BackStackRecord extends FragmentTransaction implements
break;
case OP_REPLACE: {
Fragment f = op.fragment;
+ int containerId = f.mContainerId;
if (mManager.mAdded != null) {
for (int i = 0; i < mManager.mAdded.size(); i++) {
Fragment old = mManager.mAdded.get(i);
@@ -724,7 +725,7 @@ final class BackStackRecord extends FragmentTransaction implements
Log.v(TAG,
"OP_REPLACE: adding=" + f + " old=" + old);
}
- if (f == null || old.mContainerId == f.mContainerId) {
+ if (old.mContainerId == containerId) {
if (old == f) {
op.fragment = f = null;
} else {
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 0420fb6..6639486 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1202,8 +1202,8 @@ class ContextImpl extends Context {
validateServiceIntent(service);
service.prepareToLeaveProcess();
ComponentName cn = ActivityManagerNative.getDefault().startService(
- mMainThread.getApplicationThread(), service,
- service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
+ mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
+ getContentResolver()), getOpPackageName(), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
@@ -1279,9 +1279,9 @@ class ContextImpl extends Context {
}
service.prepareToLeaveProcess();
int res = ActivityManagerNative.getDefault().bindService(
- mMainThread.getApplicationThread(), getActivityToken(),
- service, service.resolveTypeIfNeeded(getContentResolver()),
- sd, flags, user.getIdentifier());
+ mMainThread.getApplicationThread(), getActivityToken(), service,
+ service.resolveTypeIfNeeded(getContentResolver()),
+ sd, flags, getOpPackageName(), user.getIdentifier());
if (res < 0) {
throw new SecurityException(
"Not allowed to bind to service " + service);
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 0328708..acce81c 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -160,16 +160,16 @@ public interface IActivityManager extends IInterface {
public PendingIntent getRunningServiceControlPanel(ComponentName service)
throws RemoteException;
public ComponentName startService(IApplicationThread caller, Intent service,
- String resolvedType, int userId) throws RemoteException;
+ String resolvedType, String callingPackage, int userId) throws RemoteException;
public int stopService(IApplicationThread caller, Intent service,
String resolvedType, int userId) throws RemoteException;
public boolean stopServiceToken(ComponentName className, IBinder token,
int startId) throws RemoteException;
public void setServiceForeground(ComponentName className, IBinder token,
int id, Notification notification, boolean keepNotification) throws RemoteException;
- public int bindService(IApplicationThread caller, IBinder token,
- Intent service, String resolvedType,
- IServiceConnection connection, int flags, int userId) throws RemoteException;
+ public int bindService(IApplicationThread caller, IBinder token, Intent service,
+ String resolvedType, IServiceConnection connection, int flags,
+ String callingPackage, int userId) throws RemoteException;
public boolean unbindService(IServiceConnection connection) throws RemoteException;
public void publishService(IBinder token,
Intent intent, IBinder service) throws RemoteException;
@@ -178,7 +178,8 @@ public interface IActivityManager extends IInterface {
/* oneway */
public void serviceDoneExecuting(IBinder token, int type, int startId,
int res) throws RemoteException;
- public IBinder peekService(Intent service, String resolvedType) throws RemoteException;
+ public IBinder peekService(Intent service, String resolvedType, String callingPackage)
+ throws RemoteException;
public boolean bindBackupAgent(ApplicationInfo appInfo, int backupRestoreMode)
throws RemoteException;
@@ -441,6 +442,8 @@ public interface IActivityManager extends IInterface {
public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
Bundle args) throws RemoteException;
+ public boolean isScreenCaptureAllowedOnCurrentActivity() throws RemoteException;
+
public void killUid(int uid, String reason) throws RemoteException;
public void hang(IBinder who, boolean allowRestart) throws RemoteException;
@@ -852,4 +855,6 @@ public interface IActivityManager extends IInterface {
int KEYGUARD_GOING_AWAY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+296;
int REGISTER_UID_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+297;
int UNREGISTER_UID_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+298;
+ int IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION
+ = IBinder.FIRST_CALL_TRANSACTION+299;
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 83e06d6..d28ff51 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -215,7 +215,7 @@ public class DevicePolicyManager {
* <p>This component is set as device owner and active admin when device owner provisioning is
* started by an intent with action {@link #ACTION_PROVISION_MANAGED_DEVICE} or by an NFC
* message containing an NFC record with MIME type
- * {@link #MIME_TYPE_PROVISIONING_NFC_V2}. For the NFC record, the component name should be
+ * {@link #MIME_TYPE_PROVISIONING_NFC}. For the NFC record, the component name should be
* flattened to a string, via {@link ComponentName#flattenToShortString()}.
*
* @see DeviceAdminReceiver
@@ -386,7 +386,7 @@ public class DevicePolicyManager {
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION} if the version of the
* installed package is less than this version code.
*
- * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} that starts device owner
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
* provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE
@@ -461,7 +461,7 @@ public class DevicePolicyManager {
* A boolean extra indicating whether device encryption can be skipped as part of Device Owner
* provisioning.
*
- * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} or an intent with action
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} or an intent with action
* {@link #ACTION_PROVISION_MANAGED_DEVICE} that starts device owner provisioning.
*/
public static final String EXTRA_PROVISIONING_SKIP_ENCRYPTION =
@@ -558,12 +558,17 @@ public class DevicePolicyManager {
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_SIGNATURE_CHECKSUM";
/**
- * This MIME type is used for starting the Device Owner provisioning that does not require
- * provisioning features introduced in Android API level
- * {@link android.os.Build.VERSION_CODES#MNC} or later levels.
+ * This MIME type is used for starting the Device Owner provisioning.
+ *
+ * <p>During device owner provisioning a device admin app is set as the owner of the device.
+ * A device owner has full control over the device. The device owner can not be modified by the
+ * user and the only way of resetting the device is if the device owner app calls a factory
+ * reset.
*
- * <p>For more information about the provisioning process see
- * {@link #MIME_TYPE_PROVISIONING_NFC_V2}.
+ * <p> A typical use case would be a device that is owned by a company, but used by either an
+ * employee or client.
+ *
+ * <p> The NFC message should be send to an unprovisioned device.
*
* <p>The NFC record must contain a serialized {@link java.util.Properties} object which
* contains the following properties:
@@ -589,15 +594,13 @@ public class DevicePolicyManager {
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME} instead of
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}, (although specifying only
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} is still supported).
- *
- * @see #MIME_TYPE_PROVISIONING_NFC_V2
- *
*/
public static final String MIME_TYPE_PROVISIONING_NFC
= "application/com.android.managedprovisioning";
/**
+ * @hide
* This MIME type is used for starting the Device Owner provisioning that requires
* new provisioning features introduced in API version
* {@link android.os.Build.VERSION_CODES#MNC} in addition to those supported in earlier
@@ -2402,6 +2405,9 @@ public class DevicePolicyManager {
* <p>The calling device admin must be a device or profile owner. If it is not, a
* security exception will be thrown.
*
+ * <p>From version {@link android.os.Build.VERSION_CODES#MNC} disabling screen capture also
+ * blocks assist requests for all activities of the relevant user.
+ *
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param disabled Whether screen capture is disabled or not.
*/
@@ -3606,7 +3612,10 @@ public class DevicePolicyManager {
* @see UserHandle
* @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
* user could not be created.
+ *
+ * @deprecated From {@link android.os.Build.VERSION_CODES#MNC}
*/
+ @Deprecated
public UserHandle createUser(@NonNull ComponentName admin, String name) {
try {
return mService.createUser(admin, name);
@@ -3640,7 +3649,10 @@ public class DevicePolicyManager {
* @see UserHandle
* @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
* user could not be created.
+ *
+ * @deprecated From {@link android.os.Build.VERSION_CODES#MNC}
*/
+ @Deprecated
public UserHandle createAndInitializeUser(@NonNull ComponentName admin, String name,
String ownerName, @NonNull ComponentName profileOwnerComponent, Bundle adminExtras) {
try {
@@ -3956,24 +3968,27 @@ public class DevicePolicyManager {
* <li>{@link Settings.Global#ADB_ENABLED}</li>
* <li>{@link Settings.Global#AUTO_TIME}</li>
* <li>{@link Settings.Global#AUTO_TIME_ZONE}</li>
- * <li>{@link Settings.Global#BLUETOOTH_ON}
- * Changing this setting has not effect as of {@link android.os.Build.VERSION_CODES#MNC}. Use
- * {@link android.bluetooth.BluetoothAdapter#enable()} and
- * {@link android.bluetooth.BluetoothAdapter#disable()} instead.</li>
* <li>{@link Settings.Global#DATA_ROAMING}</li>
- * <li>{@link Settings.Global#DEVELOPMENT_SETTINGS_ENABLED}</li>
- * <li>{@link Settings.Global#MODE_RINGER}</li>
- * <li>{@link Settings.Global#NETWORK_PREFERENCE}</li>
* <li>{@link Settings.Global#USB_MASS_STORAGE_ENABLED}</li>
- * <li>{@link Settings.Global#WIFI_ON}
- * Changing this setting has not effect as of {@link android.os.Build.VERSION_CODES#MNC}. Use
- * {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)} instead.</li>
* <li>{@link Settings.Global#WIFI_SLEEP_POLICY}</li>
* <li>{@link Settings.Global#STAY_ON_WHILE_PLUGGED_IN}
- * This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards
- * and can only be set if {@link #setMaximumTimeToLock} is not used to set a timeout.</li>
+ * This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards
+ * and can only be set if {@link #setMaximumTimeToLock} is not used to set a timeout.</li>
* <li>{@link Settings.Global#WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN}</li>
* </ul>
+ * <p>Changing the following settings has no effect as of
+ * {@link android.os.Build.VERSION_CODES#MNC}:
+ * <ul>
+ * <li>{@link Settings.Global#BLUETOOTH_ON}.
+ * Use {@link android.bluetooth.BluetoothAdapter#enable()} and
+ * {@link android.bluetooth.BluetoothAdapter#disable()} instead.</li>
+ * <li>{@link Settings.Global#DEVELOPMENT_SETTINGS_ENABLED}</li>
+ * <li>{@link Settings.Global#MODE_RINGER}.
+ * Use {@link android.media.AudioManager#setRingerMode(int)} instead.</li>
+ * <li>{@link Settings.Global#NETWORK_PREFERENCE}</li>
+ * <li>{@link Settings.Global#WIFI_ON}.
+ * Use {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)} instead.</li>
+ * </ul>
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param setting The name of the setting to update.
diff --git a/core/java/android/app/assist/AssistContent.java b/core/java/android/app/assist/AssistContent.java
index 07b2d57..cddf47a 100644
--- a/core/java/android/app/assist/AssistContent.java
+++ b/core/java/android/app/assist/AssistContent.java
@@ -12,7 +12,6 @@ import android.os.Parcelable;
* assistant at the user's request. This is filled in by
* {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}.
*/
-@Deprecated
public class AssistContent implements Parcelable {
private boolean mIsAppProvidedIntent = false;
private Intent mIntent;
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 284dfd6..3429b6e 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -2,6 +2,7 @@ package android.app.assist;
import android.app.Activity;
import android.content.ComponentName;
+import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.Binder;
import android.os.Bundle;
@@ -128,24 +129,24 @@ public class AssistStructure implements Parcelable {
view.dispatchProvideStructure(builder);
}
- WindowNode(Parcel in, PooledStringReader preader) {
+ WindowNode(Parcel in, PooledStringReader preader, float[] tmpMatrix) {
mX = in.readInt();
mY = in.readInt();
mWidth = in.readInt();
mHeight = in.readInt();
mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
mDisplayId = in.readInt();
- mRoot = new ViewNode(in, preader);
+ mRoot = new ViewNode(in, preader, tmpMatrix);
}
- void writeToParcel(Parcel out, PooledStringWriter pwriter) {
+ int writeToParcel(Parcel out, PooledStringWriter pwriter, float[] tmpMatrix) {
out.writeInt(mX);
out.writeInt(mY);
out.writeInt(mWidth);
out.writeInt(mHeight);
TextUtils.writeToParcel(mTitle, out, 0);
out.writeInt(mDisplayId);
- mRoot.writeToParcel(out, pwriter);
+ return mRoot.writeToParcel(out, pwriter, tmpMatrix);
}
/**
@@ -216,7 +217,7 @@ public class AssistStructure implements Parcelable {
public static final int TEXT_STYLE_UNDERLINE = 1<<2;
public static final int TEXT_STYLE_STRIKE_THRU = 1<<3;
- int mId;
+ int mId = View.NO_ID;
String mIdPackage;
String mIdType;
String mIdEntry;
@@ -226,20 +227,35 @@ public class AssistStructure implements Parcelable {
int mScrollY;
int mWidth;
int mHeight;
+ Matrix mMatrix;
+ float mElevation;
+ float mAlpha = 1.0f;
static final int FLAGS_DISABLED = 0x00000001;
static final int FLAGS_VISIBILITY_MASK = View.VISIBLE|View.INVISIBLE|View.GONE;
static final int FLAGS_FOCUSABLE = 0x00000010;
static final int FLAGS_FOCUSED = 0x00000020;
- static final int FLAGS_ACCESSIBILITY_FOCUSED = 0x04000000;
static final int FLAGS_SELECTED = 0x00000040;
static final int FLAGS_ASSIST_BLOCKED = 0x00000080;
- static final int FLAGS_ACTIVATED = 0x40000000;
static final int FLAGS_CHECKABLE = 0x00000100;
static final int FLAGS_CHECKED = 0x00000200;
- static final int FLAGS_CLICKABLE = 0x00004000;
- static final int FLAGS_LONG_CLICKABLE = 0x00200000;
- static final int FLAGS_CONTEXT_CLICKABLE = 0x00400000;
+ static final int FLAGS_CLICKABLE = 0x00000400;
+ static final int FLAGS_LONG_CLICKABLE = 0x00000800;
+ static final int FLAGS_ACCESSIBILITY_FOCUSED = 0x00001000;
+ static final int FLAGS_ACTIVATED = 0x00002000;
+ static final int FLAGS_CONTEXT_CLICKABLE = 0x00004000;
+
+ static final int FLAGS_HAS_MATRIX = 0x40000000;
+ static final int FLAGS_HAS_ALPHA = 0x20000000;
+ static final int FLAGS_HAS_ELEVATION = 0x10000000;
+ static final int FLAGS_HAS_SCROLL = 0x08000000;
+ static final int FLAGS_HAS_LARGE_COORDS = 0x04000000;
+ static final int FLAGS_HAS_CONTENT_DESCRIPTION = 0x02000000;
+ static final int FLAGS_HAS_TEXT = 0x01000000;
+ static final int FLAGS_HAS_EXTRAS = 0x00800000;
+ static final int FLAGS_HAS_ID = 0x00400000;
+ static final int FLAGS_HAS_CHILDREN = 0x00200000;
+ static final int FLAGS_ALL_CONTROL = 0xfff00000;
int mFlags;
@@ -254,79 +270,153 @@ public class AssistStructure implements Parcelable {
ViewNode() {
}
- ViewNode(Parcel in, PooledStringReader preader) {
- mId = in.readInt();
- if (mId != 0) {
- mIdEntry = preader.readString();
- if (mIdEntry != null) {
- mIdType = preader.readString();
- mIdPackage = preader.readString();
- } else {
- mIdPackage = mIdType = null;
+ ViewNode(Parcel in, PooledStringReader preader, float[] tmpMatrix) {
+ mClassName = preader.readString();
+ mFlags = in.readInt();
+ final int flags = mFlags;
+ if ((flags&FLAGS_HAS_ID) != 0) {
+ mId = in.readInt();
+ if (mId != 0) {
+ mIdEntry = preader.readString();
+ if (mIdEntry != null) {
+ mIdType = preader.readString();
+ mIdPackage = preader.readString();
+ }
}
+ }
+ if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
+ mX = in.readInt();
+ mY = in.readInt();
+ mWidth = in.readInt();
+ mHeight = in.readInt();
} else {
- mIdPackage = mIdType = mIdEntry = null;
+ int val = in.readInt();
+ mX = val&0x7fff;
+ mY = (val>>16)&0x7fff;
+ val = in.readInt();
+ mWidth = val&0x7fff;
+ mHeight = (val>>16)&0x7fff;
}
- mX = in.readInt();
- mY = in.readInt();
- mScrollX = in.readInt();
- mScrollY = in.readInt();
- mWidth = in.readInt();
- mHeight = in.readInt();
- mFlags = in.readInt();
- mClassName = preader.readString();
- mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
- if (in.readInt() != 0) {
+ if ((flags&FLAGS_HAS_SCROLL) != 0) {
+ mScrollX = in.readInt();
+ mScrollY = in.readInt();
+ }
+ if ((flags&FLAGS_HAS_MATRIX) != 0) {
+ mMatrix = new Matrix();
+ in.readFloatArray(tmpMatrix);
+ mMatrix.setValues(tmpMatrix);
+ }
+ if ((flags&FLAGS_HAS_ELEVATION) != 0) {
+ mElevation = in.readFloat();
+ }
+ if ((flags&FLAGS_HAS_ALPHA) != 0) {
+ mAlpha = in.readFloat();
+ }
+ if ((flags&FLAGS_HAS_CONTENT_DESCRIPTION) != 0) {
+ mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ }
+ if ((flags&FLAGS_HAS_TEXT) != 0) {
mText = new ViewNodeText(in);
- } else {
- mText = null;
}
- mExtras = in.readBundle();
- final int NCHILDREN = in.readInt();
- if (NCHILDREN > 0) {
+ if ((flags&FLAGS_HAS_EXTRAS) != 0) {
+ mExtras = in.readBundle();
+ }
+ if ((flags&FLAGS_HAS_CHILDREN) != 0) {
+ final int NCHILDREN = in.readInt();
mChildren = new ViewNode[NCHILDREN];
for (int i=0; i<NCHILDREN; i++) {
- mChildren[i] = new ViewNode(in, preader);
+ mChildren[i] = new ViewNode(in, preader, tmpMatrix);
}
- } else {
- mChildren = null;
}
}
- void writeToParcel(Parcel out, PooledStringWriter pwriter) {
- out.writeInt(mId);
- if (mId != 0) {
- pwriter.writeString(mIdEntry);
- if (mIdEntry != null) {
- pwriter.writeString(mIdType);
- pwriter.writeString(mIdPackage);
- }
+ int writeToParcel(Parcel out, PooledStringWriter pwriter, float[] tmpMatrix) {
+ int flags = mFlags & ~FLAGS_ALL_CONTROL;
+ if (mId != View.NO_ID) {
+ flags |= FLAGS_HAS_ID;
+ }
+ if ((mX&~0x7fff) != 0 || (mY&~0x7fff) != 0
+ || (mWidth&~0x7fff) != 0 | (mHeight&~0x7fff) != 0) {
+ flags |= FLAGS_HAS_LARGE_COORDS;
+ }
+ if (mScrollX != 0 || mScrollY != 0) {
+ flags |= FLAGS_HAS_SCROLL;
+ }
+ if (mMatrix != null) {
+ flags |= FLAGS_HAS_MATRIX;
+ }
+ if (mElevation != 0) {
+ flags |= FLAGS_HAS_ELEVATION;
+ }
+ if (mAlpha != 1.0f) {
+ flags |= FLAGS_HAS_ALPHA;
+ }
+ if (mContentDescription != null) {
+ flags |= FLAGS_HAS_CONTENT_DESCRIPTION;
}
- out.writeInt(mX);
- out.writeInt(mY);
- out.writeInt(mScrollX);
- out.writeInt(mScrollY);
- out.writeInt(mWidth);
- out.writeInt(mHeight);
- out.writeInt(mFlags);
- pwriter.writeString(mClassName);
- TextUtils.writeToParcel(mContentDescription, out, 0);
if (mText != null) {
- out.writeInt(1);
- mText.writeToParcel(out);
- } else {
- out.writeInt(0);
+ flags |= FLAGS_HAS_TEXT;
+ }
+ if (mExtras != null) {
+ flags |= FLAGS_HAS_EXTRAS;
}
- out.writeBundle(mExtras);
if (mChildren != null) {
+ flags |= FLAGS_HAS_CHILDREN;
+ }
+
+ pwriter.writeString(mClassName);
+ out.writeInt(flags);
+ if ((flags&FLAGS_HAS_ID) != 0) {
+ out.writeInt(mId);
+ if (mId != 0) {
+ pwriter.writeString(mIdEntry);
+ if (mIdEntry != null) {
+ pwriter.writeString(mIdType);
+ pwriter.writeString(mIdPackage);
+ }
+ }
+ }
+ if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
+ out.writeInt(mX);
+ out.writeInt(mY);
+ out.writeInt(mWidth);
+ out.writeInt(mHeight);
+ } else {
+ out.writeInt((mY<<16) | mX);
+ out.writeInt((mHeight<<16) | mWidth);
+ }
+ if ((flags&FLAGS_HAS_SCROLL) != 0) {
+ out.writeInt(mScrollX);
+ out.writeInt(mScrollY);
+ }
+ if ((flags&FLAGS_HAS_MATRIX) != 0) {
+ mMatrix.getValues(tmpMatrix);
+ out.writeFloatArray(tmpMatrix);
+ }
+ if ((flags&FLAGS_HAS_ELEVATION) != 0) {
+ out.writeFloat(mElevation);
+ }
+ if ((flags&FLAGS_HAS_ALPHA) != 0) {
+ out.writeFloat(mAlpha);
+ }
+ if ((flags&FLAGS_HAS_CONTENT_DESCRIPTION) != 0) {
+ TextUtils.writeToParcel(mContentDescription, out, 0);
+ }
+ if ((flags&FLAGS_HAS_TEXT) != 0) {
+ mText.writeToParcel(out);
+ }
+ if ((flags&FLAGS_HAS_EXTRAS) != 0) {
+ out.writeBundle(mExtras);
+ }
+ int N = 1;
+ if ((flags&FLAGS_HAS_CHILDREN) != 0) {
final int NCHILDREN = mChildren.length;
out.writeInt(NCHILDREN);
for (int i=0; i<NCHILDREN; i++) {
- mChildren[i].writeToParcel(out, pwriter);
+ N += mChildren[i].writeToParcel(out, pwriter, tmpMatrix);
}
- } else {
- out.writeInt(0);
}
+ return N;
}
/**
@@ -408,6 +498,33 @@ public class AssistStructure implements Parcelable {
}
/**
+ * Returns the transformation that has been applied to this view, such as a translation
+ * or scaling. The returned Matrix object is owned by ViewNode; do not modify it.
+ * Returns null if there is no transformation applied to the view.
+ */
+ public Matrix getTransformation() {
+ return mMatrix;
+ }
+
+ /**
+ * Returns the visual elevation of the view, used for shadowing and other visual
+ * characterstics, as set by {@link ViewStructure#setElevation
+ * ViewStructure.setElevation(float)}.
+ */
+ public float getElevation() {
+ return mElevation;
+ }
+
+ /**
+ * Returns the alpha transformation of the view, used to reduce the overall opacity
+ * of the view's contents, as set by {@link ViewStructure#setAlpha
+ * ViewStructure.setAlpha(float)}.
+ */
+ public float getAlpha() {
+ return mAlpha;
+ }
+
+ /**
* Returns the visibility mode of this view, as per
* {@link android.view.View#getVisibility() View.getVisibility()}.
*/
@@ -646,6 +763,25 @@ public class AssistStructure implements Parcelable {
}
@Override
+ public void setTransformation(Matrix matrix) {
+ if (matrix == null) {
+ mNode.mMatrix = null;
+ } else {
+ mNode.mMatrix = new Matrix(matrix);
+ }
+ }
+
+ @Override
+ public void setElevation(float elevation) {
+ mNode.mElevation = elevation;
+ }
+
+ @Override
+ public void setAlpha(float alpha) {
+ mNode.mAlpha = alpha;
+ }
+
+ @Override
public void setVisibility(int visibility) {
mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_VISIBILITY_MASK) | visibility;
}
@@ -919,6 +1055,18 @@ public class AssistStructure implements Parcelable {
if (scrollX != 0 || scrollY != 0) {
Log.i(TAG, prefix + " Scroll: " + scrollX + "," + scrollY);
}
+ Matrix matrix = node.getTransformation();
+ if (matrix != null) {
+ Log.i(TAG, prefix + " Transformation: " + matrix);
+ }
+ float elevation = node.getElevation();
+ if (elevation != 0) {
+ Log.i(TAG, prefix + " Elevation: " + elevation);
+ }
+ float alpha = node.getAlpha();
+ if (alpha != 0) {
+ Log.i(TAG, prefix + " Alpha: " + elevation);
+ }
CharSequence contentDescription = node.getContentDescription();
if (contentDescription != null) {
Log.i(TAG, prefix + " Content description: " + contentDescription);
@@ -1010,27 +1158,33 @@ public class AssistStructure implements Parcelable {
}
if (mPendingAsyncChildren.size() > 0) {
// We waited too long, assume none of the assist structure is valid.
+ Log.w(TAG, "Skipping assist structure, waiting too long for async children (have "
+ + mPendingAsyncChildren.size() + " remaining");
skipStructure = true;
}
}
int start = out.dataPosition();
PooledStringWriter pwriter = new PooledStringWriter(out);
+ float[] tmpMatrix = new float[9];
ComponentName.writeToParcel(mActivityComponent, out);
final int N = skipStructure ? 0 : mWindowNodes.size();
out.writeInt(N);
+ int NV = 0;
for (int i=0; i<N; i++) {
- mWindowNodes.get(i).writeToParcel(out, pwriter);
+ NV += mWindowNodes.get(i).writeToParcel(out, pwriter, tmpMatrix);
}
pwriter.finish();
- Log.i(TAG, "Flattened assist data: " + (out.dataPosition() - start) + " bytes");
+ Log.i(TAG, "Flattened assist data: " + (out.dataPosition() - start) + " bytes, containing "
+ + N + " windows, " + NV + " views");
}
void readContentFromParcel(Parcel in) {
PooledStringReader preader = new PooledStringReader(in);
+ float[] tmpMatrix = new float[9];
mActivityComponent = ComponentName.readFromParcel(in);
final int N = in.readInt();
for (int i=0; i<N; i++) {
- mWindowNodes.add(new WindowNode(in, preader));
+ mWindowNodes.add(new WindowNode(in, preader, tmpMatrix));
}
//dump();
}
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index 369b692..24647f3 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -372,13 +372,4 @@ public final class UsageEvents implements Parcelable {
return new UsageEvents[size];
}
};
-
- @Override
- protected void finalize() throws Throwable {
- super.finalize();
- if (mParcel != null) {
- mParcel.recycle();
- mParcel = null;
- }
- }
}
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java
index af74e73..2260d7e 100644
--- a/core/java/android/content/BroadcastReceiver.java
+++ b/core/java/android/content/BroadcastReceiver.java
@@ -524,7 +524,7 @@ public abstract class BroadcastReceiver {
try {
service.prepareToLeaveProcess();
binder = am.peekService(service, service.resolveTypeIfNeeded(
- myContext.getContentResolver()));
+ myContext.getContentResolver()), myContext.getOpPackageName());
} catch (RemoteException e) {
}
return binder;
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index d4c4437..3cc7684 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -475,18 +475,38 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
private int enforceReadPermission(String callingPkg, Uri uri, IBinder callerToken)
throws SecurityException {
enforceReadPermissionInner(uri, callerToken);
+
+ final int permOp = AppOpsManager.permissionToOpCode(mReadPermission);
+ if (permOp != AppOpsManager.OP_NONE) {
+ final int mode = mAppOpsManager.noteProxyOp(permOp, callingPkg);
+ if (mode != AppOpsManager.MODE_ALLOWED) {
+ return mode;
+ }
+ }
+
if (mReadOp != AppOpsManager.OP_NONE) {
- return mAppOpsManager.noteOp(mReadOp, Binder.getCallingUid(), callingPkg);
+ return mAppOpsManager.noteProxyOp(mReadOp, callingPkg);
}
+
return AppOpsManager.MODE_ALLOWED;
}
private int enforceWritePermission(String callingPkg, Uri uri, IBinder callerToken)
throws SecurityException {
enforceWritePermissionInner(uri, callerToken);
+
+ final int permOp = AppOpsManager.permissionToOpCode(mWritePermission);
+ if (permOp != AppOpsManager.OP_NONE) {
+ final int mode = mAppOpsManager.noteProxyOp(permOp, callingPkg);
+ if (mode != AppOpsManager.MODE_ALLOWED) {
+ return mode;
+ }
+ }
+
if (mWriteOp != AppOpsManager.OP_NONE) {
- return mAppOpsManager.noteOp(mWriteOp, Binder.getCallingUid(), callingPkg);
+ return mAppOpsManager.noteProxyOp(mWriteOp, callingPkg);
}
+
return AppOpsManager.MODE_ALLOWED;
}
}
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index d37dda0..6ede29b 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1593,7 +1593,11 @@ public abstract class ContentResolver {
@NonNull ContentObserver observer) {
Preconditions.checkNotNull(uri, "uri");
Preconditions.checkNotNull(observer, "observer");
- registerContentObserver(uri, notifyForDescendents, observer, UserHandle.myUserId());
+ registerContentObserver(
+ ContentProvider.getUriWithoutUserId(uri),
+ notifyForDescendents,
+ observer,
+ ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId()));
}
/** @hide - designated user version */
@@ -1659,7 +1663,11 @@ public abstract class ContentResolver {
public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer,
boolean syncToNetwork) {
Preconditions.checkNotNull(uri, "uri");
- notifyChange(uri, observer, syncToNetwork, UserHandle.myUserId());
+ notifyChange(
+ ContentProvider.getUriWithoutUserId(uri),
+ observer,
+ syncToNetwork,
+ ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId()));
}
/**
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 83d6cb0..c9f9b56 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3784,6 +3784,9 @@ public class Intent implements Parcelable, Cloneable {
/** {@hide} */
public static final String EXTRA_REASON = "android.intent.extra.REASON";
+ /** {@hide} */
+ public static final String EXTRA_WIPE_EXTERNAL_STORAGE = "android.intent.extra.WIPE_EXTERNAL_STORAGE";
+
/**
* Optional {@link android.app.PendingIntent} extra used to deliver the result of the SIM
* activation request.
@@ -6178,8 +6181,12 @@ public class Intent implements Parcelable, Cloneable {
* who sent the intent.
* @hide
*/
- public void setContentUserHint(int contentUserHint) {
- mContentUserHint = contentUserHint;
+ public void prepareToLeaveUser(int userId) {
+ // If mContentUserHint is not UserHandle.USER_CURRENT, the intent has already left a user.
+ // We want mContentUserHint to refer to the original user, so don't do anything.
+ if (mContentUserHint == UserHandle.USER_CURRENT) {
+ mContentUserHint = userId;
+ }
}
/**
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index e267b52..19329ce 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -518,7 +518,8 @@ public class IntentFilter implements Parcelable {
}
/**
- * Return if this filter handle all HTTP or HTTPS data URI or not.
+ * Return if this filter handle all HTTP or HTTPS data URI or not. This is the
+ * core check for whether a given activity qualifies as a "browser".
*
* @return True if the filter handle all HTTP or HTTPS data URI. False otherwise.
*
@@ -533,23 +534,26 @@ public class IntentFilter implements Parcelable {
*/
public final boolean handleAllWebDataURI() {
return hasCategory(Intent.CATEGORY_APP_BROWSER) ||
- (hasOnlyWebDataURI() && countDataAuthorities() == 0);
+ (handlesWebUris(false) && countDataAuthorities() == 0);
}
/**
- * Return if this filter handles only HTTP or HTTPS data URIs.
+ * Return if this filter handles HTTP or HTTPS data URIs.
*
* @return True if the filter handles ACTION_VIEW/CATEGORY_BROWSABLE,
- * has at least one HTTP or HTTPS data URI pattern defined, and does not
- * define any non-http/https data URI patterns.
+ * has at least one HTTP or HTTPS data URI pattern defined, and optionally
+ * does not define any non-http/https data URI patterns.
*
* This will check if if the Intent action is {@link android.content.Intent#ACTION_VIEW} and
* the Intent category is {@link android.content.Intent#CATEGORY_BROWSABLE} and the Intent
* data scheme is "http" or "https".
*
+ * @param onlyWebSchemes When true, requires that the intent filter declare
+ * that it handles *only* http: or https: schemes. This is a requirement for
+ * the intent filter's domain linkage being verifiable.
* @hide
*/
- public final boolean hasOnlyWebDataURI() {
+ public final boolean handlesWebUris(boolean onlyWebSchemes) {
// Require ACTION_VIEW, CATEGORY_BROWSEABLE, and at least one scheme
if (!hasAction(Intent.ACTION_VIEW)
|| !hasCategory(Intent.CATEGORY_BROWSABLE)
@@ -562,13 +566,28 @@ public class IntentFilter implements Parcelable {
final int N = mDataSchemes.size();
for (int i = 0; i < N; i++) {
final String scheme = mDataSchemes.get(i);
- if (!SCHEME_HTTP.equals(scheme) && !SCHEME_HTTPS.equals(scheme)) {
- return false;
+ final boolean isWebScheme =
+ SCHEME_HTTP.equals(scheme) || SCHEME_HTTPS.equals(scheme);
+ if (onlyWebSchemes) {
+ // If we're specifically trying to ensure that there are no non-web schemes
+ // declared in this filter, then if we ever see a non-http/https scheme then
+ // we know it's a failure.
+ if (!isWebScheme) {
+ return false;
+ }
+ } else {
+ // If we see any http/https scheme declaration in this case then the
+ // filter matches what we're looking for.
+ if (isWebScheme) {
+ return true;
+ }
}
}
- // Everything passed, so it's an only-web-URIs filter
- return true;
+ // We get here if:
+ // 1) onlyWebSchemes and no non-web schemes were found, i.e success; or
+ // 2) !onlyWebSchemes and no http/https schemes were found, i.e. failure.
+ return onlyWebSchemes;
}
/**
@@ -585,7 +604,7 @@ public class IntentFilter implements Parcelable {
* @hide
*/
public final boolean needsVerification() {
- return getAutoVerify() && hasOnlyWebDataURI();
+ return getAutoVerify() && handlesWebUris(true);
}
/**
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index cb68d74..2b83d86 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -31,7 +31,6 @@ import android.content.pm.IPackageDeleteObserver2;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
-import android.content.pm.IPackagesProvider;
import android.content.pm.IOnPermissionsChangeListener;
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.InstrumentationInfo;
@@ -102,6 +101,8 @@ interface IPackageManager {
void revokeRuntimePermission(String packageName, String permissionName, int userId);
+ void resetRuntimePermissions();
+
int getPermissionFlags(String permissionName, String packageName, int userId);
void updatePermissionFlags(String permissionName, String packageName, int flagMask,
@@ -502,6 +503,7 @@ interface IPackageManager {
void addOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
void removeOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
- void grantDefaultPermissions(int userId);
- void setCarrierAppPackagesProvider(in IPackagesProvider provider);
+ int getMountExternalMode(int uid);
+
+ void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, int userId);
}
diff --git a/core/java/android/content/pm/IPackagesProvider.aidl b/core/java/android/content/pm/IPackagesProvider.aidl
deleted file mode 100644
index 7d76c88..0000000
--- a/core/java/android/content/pm/IPackagesProvider.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm;
-
-/** {@hide} */
-interface IPackagesProvider {
- String[] getPackages(int userId);
-}
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 7599bd6..ea08956 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -39,6 +39,20 @@ public abstract class PackageManagerInternal {
}
/**
+ * Provider for package names.
+ */
+ public interface SyncAdapterPackagesProvider {
+
+ /**
+ * Gets the sync adapter packages for given authority and user.
+ * @param authority The authority.
+ * @param userId The user id.
+ * @return The package names.
+ */
+ public String[] getPackages(String authority, int userId);
+ }
+
+ /**
* Sets the location provider packages provider.
* @param provider The packages provider.
*/
@@ -55,4 +69,36 @@ public abstract class PackageManagerInternal {
* @param provider The packages provider.
*/
public abstract void setVoiceInteractionPackagesProvider(PackagesProvider provider);
+
+ /**
+ * Sets the SMS packages provider.
+ * @param provider The packages provider.
+ */
+ public abstract void setSmsAppPackagesProvider(PackagesProvider provider);
+
+ /**
+ * Sets the dialer packages provider.
+ * @param provider The packages provider.
+ */
+ public abstract void setDialerAppPackagesProvider(PackagesProvider provider);
+
+ /**
+ * Sets the sync adapter packages provider.
+ * @param provider The provider.
+ */
+ public abstract void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider);
+
+ /**
+ * Requests granting of the default permissions to the current default SMS app.
+ * @param packageName The default SMS package name.
+ * @param userId The user for which to grant the permissions.
+ */
+ public abstract void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId);
+
+ /**
+ * Requests granting of the default permissions to the current default dialer app.
+ * @param packageName The default dialer package name.
+ * @param userId The user for which to grant the permissions.
+ */
+ public abstract void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId);
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index faf71ee..64376c1 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1505,7 +1505,8 @@ public class PackageParser {
if (!parseUsesPermission(pkg, res, parser, attrs)) {
return null;
}
- } else if (tagName.equals("uses-permission-sdk-m")) {
+ } else if (tagName.equals("uses-permission-sdk-m")
+ || tagName.equals("uses-permission-sdk-23")) {
if (!parseUsesPermission(pkg, res, parser, attrs)) {
return null;
}
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index 04dbff2..0a1f148 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -76,6 +76,13 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
public static final int PROTECTION_FLAG_APPOP = 0x40;
/**
+ * Additional flag for {@link #protectionLevel}, corresponding
+ * to the <code>pre23</code> value of
+ * {@link android.R.attr#protectionLevel}.
+ */
+ public static final int PROTECTION_FLAG_PRE23 = 0x80;
+
+ /**
* Mask for {@link #protectionLevel}: the basic protection type.
*/
public static final int PROTECTION_MASK_BASE = 0xf;
@@ -171,6 +178,9 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
if ((level&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
protLevel += "|appop";
}
+ if ((level&PermissionInfo.PROTECTION_FLAG_PRE23) != 0) {
+ protLevel += "|pre23";
+ }
return protLevel;
}
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index d6b1142..d456b5e 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -1568,47 +1568,41 @@ public abstract class SensorManager {
/**
* For testing purposes only. Not for third party applications.
*
- * Enable data injection mode in sensor service. This mode is
- * expected to be used only for testing purposes. If the HAL is
- * set to data injection mode, it will ignore the input from
- * physical sensors and read sensor data that is injected from
- * the test application. This mode is used for testing vendor
- * implementations for various algorithms like Rotation Vector,
- * Significant Motion, Step Counter etc.
- *
- * The tests which call this API need to have {@code
- * android.permission.LOCATION_HADWARE} permission which isn't
- * available for third party applications.
- *
- * @param enable True to set the HAL in DATA_INJECTION mode.
- * False to reset the HAL back to NORMAL mode.
+ * Initialize data injection mode and create a client for data injection. SensorService should
+ * already be operating in DATA_INJECTION mode for this call succeed. To set SensorService into
+ * DATA_INJECTION mode "adb shell dumpsys sensorservice data_injection" needs to be called
+ * through adb. Typically this is done using a host side test. This mode is expected to be used
+ * only for testing purposes. If the HAL is set to data injection mode, it will ignore the input
+ * from physical sensors and read sensor data that is injected from the test application. This
+ * mode is used for testing vendor implementations for various algorithms like Rotation Vector,
+ * Significant Motion, Step Counter etc. Not all HALs support DATA_INJECTION. This method will
+ * fail in those cases. Once this method succeeds, the test can call
+ * {@link injectSensorData(Sensor, float[], int, long)} to inject sensor data into the HAL.
+ *
+ * @param enable True to initialize a client in DATA_INJECTION mode.
+ * False to clean up the native resources.
*
* @return true if the HAL supports data injection and false
* otherwise.
* @hide
*/
@SystemApi
- public boolean enableDataInjectionMode(boolean enable) {
- return enableDataInjectionImpl(enable);
+ public boolean initDataInjection(boolean enable) {
+ return initDataInjectionImpl(enable);
}
/**
* @hide
*/
- protected abstract boolean enableDataInjectionImpl(boolean enable);
+ protected abstract boolean initDataInjectionImpl(boolean enable);
/**
* For testing purposes only. Not for third party applications.
*
- * This method is used to inject raw sensor data into the HAL.
- * Call enableDataInjection before this method to set the HAL in
- * data injection mode. This method should be called only if a
- * previous call to enableDataInjection has been successful and
- * the HAL is already in data injection mode.
- *
- * The tests which call this API need to have {@code
- * android.permission.LOCATION_HARDWARE} permission which isn't
- * available for third party applications.
+ * This method is used to inject raw sensor data into the HAL. Call {@link
+ * initDataInjection(boolean)} before this method to set the HAL in data injection mode. This
+ * method should be called only if a previous call to initDataInjection has been successful and
+ * the HAL and SensorService are already opreating in data injection mode.
*
* @param sensor The sensor to inject.
* @param values Sensor values to inject. The length of this
@@ -1650,9 +1644,6 @@ public abstract class SensorManager {
if (timestamp <= 0) {
throw new IllegalArgumentException("Negative or zero sensor timestamp");
}
- if (timestamp > SystemClock.elapsedRealtimeNanos()) {
- throw new IllegalArgumentException("Sensor timestamp into the future");
- }
return injectSensorDataImpl(sensor, values, accuracy, timestamp);
}
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index d7960af..50e1a68 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -43,7 +43,7 @@ public class SystemSensorManager extends SensorManager {
private static native void nativeClassInit();
private static native long nativeCreate(String opPackageName);
private static native int nativeGetNextSensor(long nativeInstance, Sensor sensor, int next);
- private static native int nativeEnableDataInjection(long nativeInstance, boolean enable);
+ private static native boolean nativeIsDataInjectionEnabled(long nativeInstance);
private static boolean sSensorModuleInitialized = false;
private static InjectEventQueue mInjectEventQueue = null;
@@ -64,7 +64,6 @@ public class SystemSensorManager extends SensorManager {
private final Looper mMainLooper;
private final int mTargetSdkLevel;
private final Context mContext;
- private final boolean mHasDataInjectionPermissions;
private final long mNativeInstance;
/** {@hide} */
@@ -79,21 +78,18 @@ public class SystemSensorManager extends SensorManager {
sSensorModuleInitialized = true;
nativeClassInit();
}
- mHasDataInjectionPermissions = context.checkSelfPermission(
- Manifest.permission.LOCATION_HARDWARE) == PackageManager.PERMISSION_GRANTED;
}
// initialize the sensor list
int i = 0;
- while(true) {
+ do {
Sensor sensor = new Sensor();
i = nativeGetNextSensor(mNativeInstance, sensor, i);
- if (i <= 0) {
- break;
+ if (i >= 0) {
+ mFullSensorsList.add(sensor);
+ mHandleToSensor.append(sensor.getHandle(), sensor);
}
- mFullSensorsList.add(sensor);
- mHandleToSensor.append(sensor.getHandle(), sensor);
- }
+ } while (i > 0);
}
@@ -230,23 +226,26 @@ public class SystemSensorManager extends SensorManager {
}
}
- protected boolean enableDataInjectionImpl(boolean enable) {
- if (!mHasDataInjectionPermissions) {
- throw new SecurityException("Permission denial. Calling enableDataInjection without "
- + Manifest.permission.LOCATION_HARDWARE);
- }
+ protected boolean initDataInjectionImpl(boolean enable) {
synchronized (mLock) {
- int ret = nativeEnableDataInjection(mNativeInstance, enable);
- // The HAL does not support injection. Ignore.
- if (ret != 0) {
- Log.e(TAG, "HAL does not support data injection");
- return false;
- }
- mDataInjectionMode = enable;
- // If data injection is being disabled clean up the native resources.
- if (!enable && mInjectEventQueue != null) {
- mInjectEventQueue.dispose();
- mInjectEventQueue = null;
+ if (enable) {
+ boolean isDataInjectionModeEnabled = nativeIsDataInjectionEnabled(mNativeInstance);
+ // The HAL does not support injection OR SensorService hasn't been set in DI mode.
+ if (!isDataInjectionModeEnabled) {
+ Log.e(TAG, "Data Injection mode not enabled");
+ return false;
+ }
+ mDataInjectionMode = true;
+ // Initialize a client for data_injection.
+ if (mInjectEventQueue == null) {
+ mInjectEventQueue = new InjectEventQueue(mMainLooper, this);
+ }
+ } else {
+ // If data injection is being disabled clean up the native resources.
+ if (mInjectEventQueue != null) {
+ mInjectEventQueue.dispose();
+ mInjectEventQueue = null;
+ }
}
return true;
}
@@ -254,18 +253,11 @@ public class SystemSensorManager extends SensorManager {
protected boolean injectSensorDataImpl(Sensor sensor, float[] values, int accuracy,
long timestamp) {
- if (!mHasDataInjectionPermissions) {
- throw new SecurityException("Permission denial. Calling injectSensorData without "
- + Manifest.permission.LOCATION_HARDWARE);
- }
synchronized (mLock) {
if (!mDataInjectionMode) {
Log.e(TAG, "Data injection mode not activated before calling injectSensorData");
return false;
}
- if (mInjectEventQueue == null) {
- mInjectEventQueue = new InjectEventQueue(mMainLooper, this);
- }
int ret = mInjectEventQueue.injectSensorData(sensor.getHandle(), values, accuracy,
timestamp);
// If there are any errors in data injection clean up the native resources.
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index a88b71c..4f9055b 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -2000,70 +2000,6 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
new Key<android.graphics.Rect>("android.sensor.info.activeArraySize", android.graphics.Rect.class);
/**
- * <p>The area of the image sensor which corresponds to active pixels prior to the
- * application of any geometric distortion correction.</p>
- * <p>This is the rectangle representing the size of the active region of the sensor (i.e.
- * the region that actually receives light from the scene) before any geometric correction
- * has been applied, and should be treated as the active region rectangle for any of the
- * raw formats. All metadata associated with raw processing (e.g. the lens shading
- * correction map, and radial distortion fields) treats the top, left of this rectangle as
- * the origin, (0,0).</p>
- * <p>The size of this region determines the maximum field of view and the maximum number of
- * pixels that an image from this sensor can contain, prior to the application of
- * geometric distortion correction. The effective maximum pixel dimensions of a
- * post-distortion-corrected image is given by the {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}
- * field, and the effective maximum field of view for a post-distortion-corrected image
- * can be calculated by applying the geometric distortion correction fields to this
- * rectangle, and cropping to the rectangle given in {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
- * <p>E.g. to calculate position of a pixel, (x,y), in a processed YUV output image with the
- * dimensions in {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} given the position of a pixel,
- * (x', y'), in the raw pixel array with dimensions give in
- * {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}:</p>
- * <ol>
- * <li>Choose a pixel (x', y') within the active array region of the raw buffer given in
- * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}, otherwise this pixel is considered
- * to be outside of the FOV, and will not be shown in the processed output image.</li>
- * <li>Apply geometric distortion correction to get the post-distortion pixel coordinate,
- * (x_i, y_i). When applying geometric correction metadata, note that metadata for raw
- * buffers is defined relative to the top, left of the
- * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} rectangle.</li>
- * <li>If the resulting corrected pixel coordinate is within the region given in
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, then the position of this pixel in the
- * processed output image buffer is <code>(x_i - activeArray.left, y_i - activeArray.top)</code>,
- * when the top, left coordinate of that buffer is treated as (0, 0).</li>
- * </ol>
- * <p>Thus, for pixel x',y' = (25, 25) on a sensor where {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}
- * is (100,100), {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} is (10, 10, 100, 100),
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} is (20, 20, 80, 80), and the geometric distortion
- * correction doesn't change the pixel coordinate, the resulting pixel selected in
- * pixel coordinates would be x,y = (25, 25) relative to the top,left of the raw buffer
- * with dimensions given in {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}, and would be (5, 5)
- * relative to the top,left of post-processed YUV output buffer with dimensions given in
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
- * <p>The currently supported fields that correct for geometric distortion are:</p>
- * <ol>
- * <li>android.lens.radialDistortion.</li>
- * </ol>
- * <p>If all of the geometric distortion fields are no-ops, this rectangle will be the same
- * as the post-distortion-corrected rectangle given in
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
- * <p>This rectangle is defined relative to the full pixel array; (0,0) is the top-left of
- * the full pixel array, and the size of the full pixel array is given by
- * {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}.</p>
- * <p>The pre-correction active array may be smaller than the full pixel array, since the
- * full array may include black calibration pixels or other inactive regions.</p>
- * <p><b>Units</b>: Pixel coordinates on the image sensor</p>
- * <p>This key is available on all devices.</p>
- *
- * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
- * @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
- * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
- */
- @PublicKey
- public static final Key<android.graphics.Rect> SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE =
- new Key<android.graphics.Rect>("android.sensor.info.preCorrectionActiveArraySize", android.graphics.Rect.class);
-
- /**
* <p>Range of sensitivities for {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity} supported by this
* camera device.</p>
* <p>The values are the standard ISO sensitivity values,
@@ -2252,6 +2188,70 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
new Key<Boolean>("android.sensor.info.lensShadingApplied", boolean.class);
/**
+ * <p>The area of the image sensor which corresponds to active pixels prior to the
+ * application of any geometric distortion correction.</p>
+ * <p>This is the rectangle representing the size of the active region of the sensor (i.e.
+ * the region that actually receives light from the scene) before any geometric correction
+ * has been applied, and should be treated as the active region rectangle for any of the
+ * raw formats. All metadata associated with raw processing (e.g. the lens shading
+ * correction map, and radial distortion fields) treats the top, left of this rectangle as
+ * the origin, (0,0).</p>
+ * <p>The size of this region determines the maximum field of view and the maximum number of
+ * pixels that an image from this sensor can contain, prior to the application of
+ * geometric distortion correction. The effective maximum pixel dimensions of a
+ * post-distortion-corrected image is given by the {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}
+ * field, and the effective maximum field of view for a post-distortion-corrected image
+ * can be calculated by applying the geometric distortion correction fields to this
+ * rectangle, and cropping to the rectangle given in {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
+ * <p>E.g. to calculate position of a pixel, (x,y), in a processed YUV output image with the
+ * dimensions in {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} given the position of a pixel,
+ * (x', y'), in the raw pixel array with dimensions give in
+ * {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}:</p>
+ * <ol>
+ * <li>Choose a pixel (x', y') within the active array region of the raw buffer given in
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}, otherwise this pixel is considered
+ * to be outside of the FOV, and will not be shown in the processed output image.</li>
+ * <li>Apply geometric distortion correction to get the post-distortion pixel coordinate,
+ * (x_i, y_i). When applying geometric correction metadata, note that metadata for raw
+ * buffers is defined relative to the top, left of the
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} rectangle.</li>
+ * <li>If the resulting corrected pixel coordinate is within the region given in
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, then the position of this pixel in the
+ * processed output image buffer is <code>(x_i - activeArray.left, y_i - activeArray.top)</code>,
+ * when the top, left coordinate of that buffer is treated as (0, 0).</li>
+ * </ol>
+ * <p>Thus, for pixel x',y' = (25, 25) on a sensor where {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}
+ * is (100,100), {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} is (10, 10, 100, 100),
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} is (20, 20, 80, 80), and the geometric distortion
+ * correction doesn't change the pixel coordinate, the resulting pixel selected in
+ * pixel coordinates would be x,y = (25, 25) relative to the top,left of the raw buffer
+ * with dimensions given in {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}, and would be (5, 5)
+ * relative to the top,left of post-processed YUV output buffer with dimensions given in
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
+ * <p>The currently supported fields that correct for geometric distortion are:</p>
+ * <ol>
+ * <li>android.lens.radialDistortion.</li>
+ * </ol>
+ * <p>If all of the geometric distortion fields are no-ops, this rectangle will be the same
+ * as the post-distortion-corrected rectangle given in
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
+ * <p>This rectangle is defined relative to the full pixel array; (0,0) is the top-left of
+ * the full pixel array, and the size of the full pixel array is given by
+ * {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}.</p>
+ * <p>The pre-correction active array may be smaller than the full pixel array, since the
+ * full array may include black calibration pixels or other inactive regions.</p>
+ * <p><b>Units</b>: Pixel coordinates on the image sensor</p>
+ * <p>This key is available on all devices.</p>
+ *
+ * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
+ */
+ @PublicKey
+ public static final Key<android.graphics.Rect> SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE =
+ new Key<android.graphics.Rect>("android.sensor.info.preCorrectionActiveArraySize", android.graphics.Rect.class);
+
+ /**
* <p>The standard reference illuminant used as the scene light source when
* calculating the {@link CameraCharacteristics#SENSOR_COLOR_TRANSFORM1 android.sensor.colorTransform1},
* {@link CameraCharacteristics#SENSOR_CALIBRATION_TRANSFORM1 android.sensor.calibrationTransform1}, and
@@ -2738,35 +2738,13 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
/**
* <p>The maximum number of frames that can occur after a request
* (different than the previous) has been submitted, and before the
- * result's state becomes synchronized (by setting
- * android.sync.frameNumber to a non-negative value).</p>
+ * result's state becomes synchronized.</p>
* <p>This defines the maximum distance (in number of metadata results),
- * between android.sync.frameNumber and the equivalent
- * frame number for that result.</p>
+ * between the frame number of the request that has new controls to apply
+ * and the frame number of the result that has all the controls applied.</p>
* <p>In other words this acts as an upper boundary for how many frames
* must occur before the camera device knows for a fact that the new
* submitted camera settings have been applied in outgoing frames.</p>
- * <p>For example if the distance was 2,</p>
- * <pre><code>initial request = X (repeating)
- * request1 = X
- * request2 = Y
- * request3 = Y
- * request4 = Y
- *
- * where requestN has frameNumber N, and the first of the repeating
- * initial request's has frameNumber F (and F &lt; 1).
- *
- * initial result = X' + { android.sync.frameNumber == F }
- * result1 = X' + { android.sync.frameNumber == F }
- * result2 = X' + { android.sync.frameNumber == CONVERGING }
- * result3 = X' + { android.sync.frameNumber == CONVERGING }
- * result4 = X' + { android.sync.frameNumber == 2 }
- *
- * where resultN has frameNumber N.
- * </code></pre>
- * <p>Since <code>result4</code> has a <code>frameNumber == 4</code> and
- * <code>android.sync.frameNumber == 2</code>, the distance is clearly
- * <code>4 - 2 = 2</code>.</p>
* <p><b>Units</b>: Frame counts</p>
* <p><b>Possible values:</b>
* <ul>
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 006030c..639c8b1 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -236,13 +236,16 @@ public abstract class CameraDevice implements AutoCloseable {
* {@link CameraCaptureSession.StateCallback}'s
* {@link CameraCaptureSession.StateCallback#onConfigured} callback will be called.</p>
*
- * <p>If a prior CameraCaptureSession already exists when a new one is created, the previous
- * session is closed. Any in-progress capture requests made on the prior session will be
- * completed before the new session is configured and is able to start capturing its own
- * requests. To minimize the transition time, the {@link CameraCaptureSession#abortCaptures}
- * call can be used to discard the remaining requests for the prior capture session before a new
- * one is created. Note that once the new session is created, the old one can no longer have its
- * captures aborted.</p>
+ * <p>If a prior CameraCaptureSession already exists when this method is called, the previous
+ * session will no longer be able to accept new capture requests and will be closed. Any
+ * in-progress capture requests made on the prior session will be completed before it's closed.
+ * {@link CameraCaptureSession.StateListener#onConfigured} for the new session may be invoked
+ * before {@link CameraCaptureSession.StateListener#onClosed} is invoked for the prior
+ * session. Once the new session is {@link CameraCaptureSession.StateListener#onConfigured
+ * configured}, it is able to start capturing its own requests. To minimize the transition time,
+ * the {@link CameraCaptureSession#abortCaptures} call can be used to discard the remaining
+ * requests for the prior capture session before a new one is created. Note that once the new
+ * session is created, the old one can no longer have its captures aborted.</p>
*
* <p>Using larger resolution outputs, or more outputs, can result in slower
* output rate from the device.</p>
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 5a80585..e8dbc5b 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -955,8 +955,6 @@ public abstract class CameraMetadata<TKey> {
/**
* <p>Every frame has the requests immediately applied.</p>
- * <p>Furthermore for all results,
- * <code>android.sync.frameNumber == {@link android.hardware.camera2.CaptureResult#getFrameNumber }</code></p>
* <p>Changing controls over multiple requests one after another will
* produce results that have those controls applied atomically
* each frame.</p>
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 75289f7..33cc962 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1062,6 +1062,15 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* capturing a high-resolution JPEG image will automatically trigger a
* precapture sequence before the high-resolution capture, including
* potentially firing a pre-capture flash.</p>
+ * <p>Using the precapture trigger and the auto-focus trigger {@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}
+ * simultaneously is allowed. However, since these triggers often require cooperation between
+ * the auto-focus and auto-exposure routines (for example, the may need to be enabled for a
+ * focus sweep), the camera device may delay acting on a later trigger until the previous
+ * trigger has been fully handled. This may lead to longer intervals between the trigger and
+ * changes to {@link CaptureResult#CONTROL_AE_STATE android.control.aeState} indicating the start of the precapture sequence, for
+ * example.</p>
+ * <p>If both the precapture and the auto-focus trigger are activated on the same request, then
+ * the camera device will complete them in the optimal order for that device.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE IDLE}</li>
@@ -1075,6 +1084,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
*
* @see CaptureRequest#CONTROL_AE_LOCK
* @see CaptureResult#CONTROL_AE_STATE
+ * @see CaptureRequest#CONTROL_AF_TRIGGER
* @see CaptureRequest#CONTROL_CAPTURE_INTENT
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE
@@ -1179,6 +1189,12 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* START for multiple captures in a row means restarting the AF operation over
* and over again.</p>
* <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what the trigger means for each AF mode.</p>
+ * <p>Using the autofocus trigger and the precapture trigger {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}
+ * simultaneously is allowed. However, since these triggers often require cooperation between
+ * the auto-focus and auto-exposure routines (for example, the may need to be enabled for a
+ * focus sweep), the camera device may delay acting on a later trigger until the previous
+ * trigger has been fully handled. This may lead to longer intervals between the trigger and
+ * changes to {@link CaptureResult#CONTROL_AF_STATE android.control.afState}, for example.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #CONTROL_AF_TRIGGER_IDLE IDLE}</li>
@@ -1187,6 +1203,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* </ul></p>
* <p>This key is available on all devices.</p>
*
+ * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
* @see CaptureResult#CONTROL_AF_STATE
* @see #CONTROL_AF_TRIGGER_IDLE
* @see #CONTROL_AF_TRIGGER_START
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 1d31109..9dee045 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -779,6 +779,15 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* capturing a high-resolution JPEG image will automatically trigger a
* precapture sequence before the high-resolution capture, including
* potentially firing a pre-capture flash.</p>
+ * <p>Using the precapture trigger and the auto-focus trigger {@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}
+ * simultaneously is allowed. However, since these triggers often require cooperation between
+ * the auto-focus and auto-exposure routines (for example, the may need to be enabled for a
+ * focus sweep), the camera device may delay acting on a later trigger until the previous
+ * trigger has been fully handled. This may lead to longer intervals between the trigger and
+ * changes to {@link CaptureResult#CONTROL_AE_STATE android.control.aeState} indicating the start of the precapture sequence, for
+ * example.</p>
+ * <p>If both the precapture and the auto-focus trigger are activated on the same request, then
+ * the camera device will complete them in the optimal order for that device.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE IDLE}</li>
@@ -792,6 +801,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
*
* @see CaptureRequest#CONTROL_AE_LOCK
* @see CaptureResult#CONTROL_AE_STATE
+ * @see CaptureRequest#CONTROL_AF_TRIGGER
* @see CaptureRequest#CONTROL_CAPTURE_INTENT
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE
@@ -1139,6 +1149,12 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* START for multiple captures in a row means restarting the AF operation over
* and over again.</p>
* <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what the trigger means for each AF mode.</p>
+ * <p>Using the autofocus trigger and the precapture trigger {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}
+ * simultaneously is allowed. However, since these triggers often require cooperation between
+ * the auto-focus and auto-exposure routines (for example, the may need to be enabled for a
+ * focus sweep), the camera device may delay acting on a later trigger until the previous
+ * trigger has been fully handled. This may lead to longer intervals between the trigger and
+ * changes to {@link CaptureResult#CONTROL_AF_STATE android.control.afState}, for example.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #CONTROL_AF_TRIGGER_IDLE IDLE}</li>
@@ -1147,6 +1163,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* </ul></p>
* <p>This key is available on all devices.</p>
*
+ * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
* @see CaptureResult#CONTROL_AF_STATE
* @see #CONTROL_AF_TRIGGER_IDLE
* @see #CONTROL_AF_TRIGGER_START
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 0484806..f596c93 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -26,7 +26,7 @@ import java.util.List;
*/
interface IFingerprintService {
// Authenticate the given sessionId with a fingerprint
- void authenticate(IBinder token, long sessionId, int groupId,
+ void authenticate(IBinder token, long sessionId, int userId,
IFingerprintServiceReceiver receiver, int flags, String opPackageName);
// Cancel authentication for the given sessionId
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 80476ea..12cd5f1 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2565,7 +2565,7 @@ public class ConnectivityManager {
* replaced by this one, effectively releasing the previous {@link NetworkRequest}.
* <p>
* The request may be released normally by calling
- * {@link #releaseNetworkRequest(android.app.PendingIntent)}.
+ * {@link #unregisterNetworkCallback(android.app.PendingIntent)}.
* <p>This method requires the caller to hold the permission
* {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* @param request {@link NetworkRequest} describing this request.
@@ -2619,6 +2619,19 @@ public class ConnectivityManager {
}
/**
+ * Unregisters a callback previously registered via
+ * {@link #registerNetworkCallback(NetworkRequest, android.app.PendingIntent)}.
+ *
+ * @param operation A PendingIntent equal (as defined by {@link Intent#filterEquals}) to the
+ * PendingIntent passed to
+ * {@link #registerNetworkCallback(NetworkRequest, android.app.PendingIntent)}.
+ * Cannot be null.
+ */
+ public void unregisterNetworkCallback(PendingIntent operation) {
+ releaseNetworkRequest(operation);
+ }
+
+ /**
* Informs the system whether it should switch to {@code network} regardless of whether it is
* validated or not. If {@code accept} is true, and the network was explicitly selected by the
* user (e.g., by selecting a Wi-Fi network in the Settings app), then the network will become
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 31aedad..cfd5bf1 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -517,7 +517,7 @@ public final class LinkProperties implements Parcelable {
* Note that Http Proxies are only a hint - the system recommends their use, but it does
* not enforce it and applications may ignore them.
*
- * @param proxy A {@link ProxyInfo} defining the Http Proxy to use on this link.
+ * @param proxy A {@link ProxyInfo} defining the HTTP Proxy to use on this link.
* @hide
*/
public void setHttpProxy(ProxyInfo proxy) {
@@ -774,6 +774,43 @@ public final class LinkProperties implements Parcelable {
}
/**
+ * Evaluate whether the {@link InetAddress} is considered reachable.
+ *
+ * @return {@code true} if the given {@link InetAddress} is considered reachable,
+ * {@code false} otherwise.
+ * @hide
+ */
+ public boolean isReachable(InetAddress ip) {
+ final List<RouteInfo> allRoutes = getAllRoutes();
+ // If we don't have a route to this IP address, it's not reachable.
+ final RouteInfo bestRoute = RouteInfo.selectBestRoute(allRoutes, ip);
+ if (bestRoute == null) {
+ return false;
+ }
+
+ // TODO: better source address evaluation for destination addresses.
+
+ if (ip instanceof Inet4Address) {
+ // For IPv4, it suffices for now to simply have any address.
+ return hasIPv4Address();
+ } else if (ip instanceof Inet6Address) {
+ if (ip.isLinkLocalAddress()) {
+ // For now, just make sure link-local destinations have
+ // scopedIds set, since transmits will generally fail otherwise.
+ // TODO: verify it matches the ifindex of one of the interfaces.
+ return (((Inet6Address)ip).getScopeId() != 0);
+ } else {
+ // For non-link-local destinations check that either the best route
+ // is directly connected or that some global preferred address exists.
+ // TODO: reconsider all cases (disconnected ULA networks, ...).
+ return (!bestRoute.hasGateway() || hasGlobalIPv6Address());
+ }
+ }
+
+ return false;
+ }
+
+ /**
* Compares this {@code LinkProperties} interface name against the target
*
* @param target LinkProperties to compare.
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index 76bd0ec..d619c0a 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -406,7 +406,7 @@ public final class NfcActivityManager extends IAppCallback.Stub
Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
}
- return new BeamShareData(message, uris, UserHandle.CURRENT, flags);
+ return new BeamShareData(message, uris, new UserHandle(UserHandle.myUserId()), flags);
}
/** Callback from NFC service, usually on binder thread */
diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
index 64c2bc2..23d05bd 100644
--- a/core/java/android/nfc/cardemulation/CardEmulation.java
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -40,7 +40,7 @@ import java.util.List;
* NFC card emulation services.
*
* For a general introduction into NFC card emulation,
- * please read the <a href="{@docRoot}guide/topics/nfc/ce.html">
+ * please read the <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">
* NFC card emulation developer guide</a>.</p>
*
* <p class="note">Use of this class requires the
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 7fda30a..fe323f3 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -184,6 +184,7 @@ public abstract class BatteryStats implements Parcelable {
private static final String UID_DATA = "uid";
private static final String APK_DATA = "apk";
private static final String PROCESS_DATA = "pr";
+ private static final String CPU_DATA = "cpu";
private static final String SENSOR_DATA = "sr";
private static final String VIBRATOR_DATA = "vib";
private static final String FOREGROUND_DATA = "fg";
@@ -457,8 +458,13 @@ public abstract class BatteryStats implements Parcelable {
public abstract long getSystemCpuTimeUs(int which);
/**
+ * Get the total cpu power consumed (in milli-ampere-microseconds).
+ */
+ public abstract long getCpuPowerMaUs(int which);
+
+ /**
* Returns the approximate cpu time (in milliseconds) spent at a certain CPU speed.
- * @param speedStep the index of the CPU speed. This is not the actual speed of the CPU.
+ * @param step the index of the CPU speed. This is not the actual speed of the CPU.
* @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
* @see BatteryStats#getCpuSpeedSteps()
*/
@@ -2905,6 +2911,14 @@ public abstract class BatteryStats implements Parcelable {
dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes);
}
+ final long userCpuTimeUs = u.getUserCpuTimeUs(which);
+ final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
+ final long powerCpuMaUs = u.getCpuPowerMaUs(which);
+ if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) {
+ dumpLine(pw, uid, category, CPU_DATA, userCpuTimeUs / 1000, systemCpuTimeUs / 1000,
+ powerCpuMaUs / 1000);
+ }
+
final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
= u.getProcessStats();
for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
@@ -2970,6 +2984,10 @@ public abstract class BatteryStats implements Parcelable {
printer.print(BatteryStatsHelper.makemAh(power));
}
+ private void printmAh(StringBuilder sb, double power) {
+ sb.append(BatteryStatsHelper.makemAh(power));
+ }
+
/**
* Temporary for settings.
*/
@@ -4028,13 +4046,17 @@ public abstract class BatteryStats implements Parcelable {
final long userCpuTimeUs = u.getUserCpuTimeUs(which);
final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
- if (userCpuTimeUs > 0 || systemCpuTimeUs > 0) {
+ final long powerCpuMaUs = u.getCpuPowerMaUs(which);
+ if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) {
sb.setLength(0);
sb.append(prefix);
sb.append(" Total cpu time: u=");
formatTimeMs(sb, userCpuTimeUs / 1000);
sb.append("s=");
formatTimeMs(sb, systemCpuTimeUs / 1000);
+ sb.append("p=");
+ printmAh(sb, powerCpuMaUs / (1000.0 * 1000.0 * 60.0 * 60.0));
+ sb.append("mAh");
pw.println(sb.toString());
}
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 50eed3e..b2ced7f 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -622,7 +622,7 @@ public class Build {
/**
* M comes after L.
*/
- public static final int MNC = CUR_DEVELOPMENT;
+ public static final int MNC = 23;
}
/** The type of build, like "user" or "eng". */
diff --git a/core/java/android/os/DeadObjectException.java b/core/java/android/os/DeadObjectException.java
index 94c5387..e06b0f9 100644
--- a/core/java/android/os/DeadObjectException.java
+++ b/core/java/android/os/DeadObjectException.java
@@ -25,4 +25,8 @@ public class DeadObjectException extends RemoteException {
public DeadObjectException() {
super();
}
+
+ public DeadObjectException(String message) {
+ super(message);
+ }
}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index f9c50f3..7234e98 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -643,6 +643,10 @@ public class Process {
}
if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
argsForZygote.add("--mount-external-default");
+ } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
+ argsForZygote.add("--mount-external-read");
+ } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
+ argsForZygote.add("--mount-external-write");
}
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
@@ -802,7 +806,12 @@ public class Process {
* @hide
*/
public static final boolean isIsolated() {
- int uid = UserHandle.getAppId(myUid());
+ return isIsolated(myUid());
+ }
+
+ /** {@hide} */
+ public static final boolean isIsolated(int uid) {
+ uid = UserHandle.getAppId(uid);
return uid >= FIRST_ISOLATED_UID && uid <= LAST_ISOLATED_UID;
}
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 6874e77..20bcf62 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -179,6 +179,19 @@ public final class UserHandle implements Parcelable {
}
/**
+ * Returns the app id for a given shared app gid.
+ * @hide
+ */
+ public static final int getAppIdFromSharedAppGid(int gid) {
+ final int noUserGid = getAppId(gid);
+ if (noUserGid < Process.FIRST_SHARED_APPLICATION_GID ||
+ noUserGid > Process.LAST_SHARED_APPLICATION_GID) {
+ throw new IllegalArgumentException(Integer.toString(gid) + " is not a shared app gid");
+ }
+ return (noUserGid + Process.FIRST_APPLICATION_UID) - Process.FIRST_SHARED_APPLICATION_GID;
+ }
+
+ /**
* Generate a text representation of the uid, breaking out its individual
* components -- user, app, isolated, etc.
* @hide
@@ -208,6 +221,17 @@ public final class UserHandle implements Parcelable {
* components -- user, app, isolated, etc.
* @hide
*/
+ public static String formatUid(int uid) {
+ StringBuilder sb = new StringBuilder();
+ formatUid(sb, uid);
+ return sb.toString();
+ }
+
+ /**
+ * Generate a text representation of the uid, breaking out its individual
+ * components -- user, app, isolated, etc.
+ * @hide
+ */
public static void formatUid(PrintWriter pw, int uid) {
if (uid < Process.FIRST_APPLICATION_UID) {
pw.print(uid);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 9770941..b104135 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -449,6 +449,8 @@ public class UserManager {
public static final String DISALLOW_RECORD_AUDIO = "no_record_audio";
/**
+ * Allows apps in the parent profile to handle web links from the managed profile.
+ *
* This user restriction has an effect only in a managed profile.
* If set:
* Intent filters of activities in the parent profile with action
@@ -462,7 +464,8 @@ public class UserManager {
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
- public static final String ALLOW_PARENT_APP_LINKING = "allow_parent_app_linking";
+ public static final String ALLOW_PARENT_PROFILE_APP_LINKING
+ = "allow_parent_profile_app_linking";
/**
* Application restriction key that is used to indicate the pending arrival
@@ -569,6 +572,16 @@ public class UserManager {
}
/**
+ * @hide
+ * Returns whether the caller is running as an admin user. There can be more than one admin
+ * user.
+ */
+ public boolean isAdminUser() {
+ UserInfo user = getUserInfo(UserHandle.myUserId());
+ return user != null ? user.isAdmin() : false;
+ }
+
+ /**
* Used to check if the user making this call is linked to another user. Linked users may have
* a reduced number of available apps, app restrictions and account restrictions.
* @return whether the user making this call is a linked user
diff --git a/core/java/android/os/storage/DiskInfo.java b/core/java/android/os/storage/DiskInfo.java
index 397d87e..9114107 100644
--- a/core/java/android/os/storage/DiskInfo.java
+++ b/core/java/android/os/storage/DiskInfo.java
@@ -54,6 +54,7 @@ public class DiskInfo implements Parcelable {
public String label;
/** Hacky; don't rely on this count */
public int volumeCount;
+ public String sysPath;
public DiskInfo(String id, int flags) {
this.id = Preconditions.checkNotNull(id);
@@ -66,6 +67,7 @@ public class DiskInfo implements Parcelable {
size = parcel.readLong();
label = parcel.readString();
volumeCount = parcel.readInt();
+ sysPath = parcel.readString();
}
public @NonNull String getId() {
@@ -139,6 +141,8 @@ public class DiskInfo implements Parcelable {
pw.printPair("flags", DebugUtils.flagsToString(getClass(), "FLAG_", flags));
pw.printPair("size", size);
pw.printPair("label", label);
+ pw.println();
+ pw.printPair("sysPath", sysPath);
pw.decreaseIndent();
pw.println();
}
@@ -193,5 +197,6 @@ public class DiskInfo implements Parcelable {
parcel.writeLong(size);
parcel.writeString(label);
parcel.writeInt(volumeCount);
+ parcel.writeString(sysPath);
}
}
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index e55ae99..84a879c 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -1177,6 +1177,21 @@ public interface IMountService extends IInterface {
_data.recycle();
}
}
+
+ @Override
+ public void remountUid(int uid) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeInt(uid);
+ mRemote.transact(Stub.TRANSACTION_remountUid, _data, _reply, 0);
+ _reply.readException();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
}
private static final String DESCRIPTOR = "IMountService";
@@ -1292,6 +1307,8 @@ public interface IMountService extends IInterface {
static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59;
static final int TRANSACTION_setDebugFlags = IBinder.FIRST_CALL_TRANSACTION + 60;
+ static final int TRANSACTION_remountUid = IBinder.FIRST_CALL_TRANSACTION + 61;
+
/**
* Cast an IBinder object into an IMountService interface, generating a
* proxy if needed.
@@ -1845,6 +1862,13 @@ public interface IMountService extends IInterface {
reply.writeNoException();
return true;
}
+ case TRANSACTION_remountUid: {
+ data.enforceInterface(DESCRIPTOR);
+ int uid = data.readInt();
+ remountUid(uid);
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
}
@@ -2154,4 +2178,6 @@ public interface IMountService extends IInterface {
public String getPrimaryStorageUuid() throws RemoteException;
public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
throws RemoteException;
+
+ public void remountUid(int uid) throws RemoteException;
}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 9b26f24..aab68e9 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -871,6 +871,15 @@ public class StorageManager {
}
/** {@hide} */
+ public void remountUid(int uid) {
+ try {
+ mMountService.remountUid(uid);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ /** {@hide} */
private static final int DEFAULT_THRESHOLD_PERCENTAGE = 10;
private static final long DEFAULT_THRESHOLD_MAX_BYTES = 500 * MB_IN_BYTES;
private static final long DEFAULT_FULL_THRESHOLD_BYTES = MB_IN_BYTES;
diff --git a/core/java/android/os/storage/VolumeRecord.java b/core/java/android/os/storage/VolumeRecord.java
index cb16305..7b20223 100644
--- a/core/java/android/os/storage/VolumeRecord.java
+++ b/core/java/android/os/storage/VolumeRecord.java
@@ -19,6 +19,7 @@ package android.os.storage;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.DebugUtils;
+import android.util.TimeUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
@@ -42,6 +43,9 @@ public class VolumeRecord implements Parcelable {
public String partGuid;
public String nickname;
public int userFlags;
+ public long createdMillis;
+ public long lastTrimMillis;
+ public long lastBenchMillis;
public VolumeRecord(int type, String fsUuid) {
this.type = type;
@@ -54,6 +58,9 @@ public class VolumeRecord implements Parcelable {
partGuid = parcel.readString();
nickname = parcel.readString();
userFlags = parcel.readInt();
+ createdMillis = parcel.readLong();
+ lastTrimMillis = parcel.readLong();
+ lastBenchMillis = parcel.readLong();
}
public int getType() {
@@ -86,6 +93,10 @@ public class VolumeRecord implements Parcelable {
pw.printPair("nickname", nickname);
pw.printPair("userFlags",
DebugUtils.flagsToString(VolumeRecord.class, "USER_FLAG_", userFlags));
+ pw.println();
+ pw.printPair("createdMillis", TimeUtils.formatForLogging(createdMillis));
+ pw.printPair("lastTrimMillis", TimeUtils.formatForLogging(lastTrimMillis));
+ pw.printPair("lastBenchMillis", TimeUtils.formatForLogging(lastBenchMillis));
pw.decreaseIndent();
pw.println();
}
@@ -140,5 +151,8 @@ public class VolumeRecord implements Parcelable {
parcel.writeString(partGuid);
parcel.writeString(nickname);
parcel.writeInt(userFlags);
+ parcel.writeLong(createdMillis);
+ parcel.writeLong(lastTrimMillis);
+ parcel.writeLong(lastBenchMillis);
}
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 9b5fbfa..4e13758 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -562,6 +562,21 @@ public final class Settings {
"android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
/**
+ * Activity Action: Show settings to toggle permission to draw on top of
+ * other apps.
+ * <p>
+ * In some cases, a matching Activity may not exist, so ensure you
+ * safeguard against this.
+ * <p>
+ * Input: Nothing.
+ * <p>
+ * Output: Nothing.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_MANAGE_OVERLAY_PERMISSION =
+ "android.settings.MANAGE_OVERLAY_PERMISSION";
+
+ /**
* Activity Action: Show screen of details about a particular application.
* <p>
* In some cases, a matching Activity may not exist, so ensure you
@@ -5444,6 +5459,14 @@ public final class Settings {
public static final String ASSIST_STRUCTURE_ENABLED = "assist_structure_enabled";
/**
+ * Specifies whether a screenshot of the screen contents will be sent to the assist
+ * application (active voice interaction service).
+ *
+ * @hide
+ */
+ public static final String ASSIST_SCREENSHOT_ENABLED = "assist_screenshot_enabled";
+
+ /**
* Names of the service components that the current user has explicitly allowed to
* see all of the user's notifications, separated by ':'.
*
@@ -6301,6 +6324,9 @@ public final class Settings {
/** Timeout in milliseconds to wait for NTP server. {@hide} */
public static final String NTP_TIMEOUT = "ntp_timeout";
+ /** {@hide} */
+ public static final String STORAGE_BENCHMARK_INTERVAL = "storage_benchmark_interval";
+
/**
* Whether the package manager should send package verification broadcasts for verifiers to
* review apps prior to installation.
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 0309d24..d424546 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -369,7 +369,9 @@ public abstract class NotificationListenerService extends Service {
/**
* Inform the notification manager that these notifications have been viewed by the
- * user.
+ * user. This should only be called when there is sufficient confidence that the user is
+ * looking at the notifications, such as when the notifications appear on the screen due to
+ * an explicit user interaction.
* @param keys Notifications to mark as seen.
*/
public final void setNotificationsShown(String[] keys) {
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 8119049..549c93e 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -172,15 +172,6 @@ public class VoiceInteractionService extends Service {
}
}
- /** @hide */
- public void startSession(Bundle args, int flags) {
- showSession(args, flags);
- }
- /** @hide */
- public void startSession(Bundle args) {
- startSession(args, 0);
- }
-
@Override
public void onCreate() {
super.onCreate();
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index f9e216a..a7e0e08 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -71,7 +71,7 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
*/
public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCallbacks2 {
static final String TAG = "VoiceInteractionSession";
- static final boolean DEBUG = true;
+ static final boolean DEBUG = false;
/**
* Flag received in {@link #onShow}: originator requested that the session be started with
@@ -175,6 +175,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
CommandRequest request = new CommandRequest(callingPackage,
Binder.getCallingUid(), callback, VoiceInteractionSession.this,
command, extras);
+ addRequest(request);
mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_START_COMMAND,
request));
return request.mInterface;
@@ -249,16 +250,12 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
}
};
- /** @hide */
- public static class Caller {
- }
-
/**
* Base class representing a request from a voice-driver app to perform a particular
* voice operation with the user. See related subclasses for the types of requests
* that are possible.
*/
- public static class Request extends Caller {
+ public static class Request {
final IVoiceInteractorRequest mInterface = new IVoiceInteractorRequest.Stub() {
@Override
public void cancel() throws RemoteException {
@@ -319,74 +316,8 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
}
}
- /** @hide */
- public void sendConfirmResult(boolean confirmed, Bundle result) {
- try {
- if (DEBUG) Log.d(TAG, "sendConfirmResult: req=" + mInterface
- + " confirmed=" + confirmed + " result=" + result);
- finishRequest();
- mCallback.deliverConfirmationResult(mInterface, confirmed, result);
- } catch (RemoteException e) {
- }
- }
-
- /** @hide */
- public void sendPickOptionResult(boolean finished,
- VoiceInteractor.PickOptionRequest.Option[] selections, Bundle result) {
- try {
- if (DEBUG) Log.d(TAG, "sendPickOptionResult: req=" + mInterface
- + " finished=" + finished + " selections=" + selections
- + " result=" + result);
- if (finished) {
- finishRequest();
- }
- mCallback.deliverPickOptionResult(mInterface, finished, selections, result);
- } catch (RemoteException e) {
- }
- }
-
- /** @hide */
- public void sendCompleteVoiceResult(Bundle result) {
- try {
- if (DEBUG) Log.d(TAG, "sendCompleteVoiceResult: req=" + mInterface
- + " result=" + result);
- finishRequest();
- mCallback.deliverCompleteVoiceResult(mInterface, result);
- } catch (RemoteException e) {
- }
- }
-
- /** @hide */
- public void sendAbortVoiceResult(Bundle result) {
- try {
- if (DEBUG) Log.d(TAG, "sendConfirmResult: req=" + mInterface
- + " result=" + result);
- finishRequest();
- mCallback.deliverAbortVoiceResult(mInterface, result);
- } catch (RemoteException e) {
- }
- }
-
- /** @hide */
- public void sendCommandResult(boolean finished, Bundle result) {
- try {
- if (DEBUG) Log.d(TAG, "sendCommandResult: req=" + mInterface
- + " result=" + result);
- if (finished) {
- finishRequest();
- }
- mCallback.deliverCommandResult(mInterface, finished, result);
- } catch (RemoteException e) {
- }
- }
-
- /** @hide */
- public void sendCancelResult() {
- cancel();
- }
-
/**
- * ASk the app to cancelLocked this current request.
+ * Ask the app to cancel this current request.
*/
public void cancel() {
try {
@@ -440,7 +371,13 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
* VoiceInteractor.ConfirmationRequest.onConfirmationResult}.
*/
public void sendConfirmationResult(boolean confirmed, Bundle result) {
- sendConfirmResult(confirmed, result);
+ try {
+ if (DEBUG) Log.d(TAG, "sendConfirmationResult: req=" + mInterface
+ + " confirmed=" + confirmed + " result=" + result);
+ finishRequest();
+ mCallback.deliverConfirmationResult(mInterface, confirmed, result);
+ } catch (RemoteException e) {
+ }
}
}
@@ -487,6 +424,20 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
return mOptions;
}
+ void sendPickOptionResult(boolean finished,
+ VoiceInteractor.PickOptionRequest.Option[] selections, Bundle result) {
+ try {
+ if (DEBUG) Log.d(TAG, "sendPickOptionResult: req=" + mInterface
+ + " finished=" + finished + " selections=" + selections
+ + " result=" + result);
+ if (finished) {
+ finishRequest();
+ }
+ mCallback.deliverPickOptionResult(mInterface, finished, selections, result);
+ } catch (RemoteException e) {
+ }
+ }
+
/**
* Report an intermediate option selection from the request, without completing it (the
* request is still active and the app is waiting for the final option selection),
@@ -553,7 +504,13 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
* VoiceInteractor.CompleteVoiceRequest.onCompleteResult}.
*/
public void sendCompleteResult(Bundle result) {
- sendCompleteVoiceResult(result);
+ try {
+ if (DEBUG) Log.d(TAG, "sendCompleteVoiceResult: req=" + mInterface
+ + " result=" + result);
+ finishRequest();
+ mCallback.deliverCompleteVoiceResult(mInterface, result);
+ } catch (RemoteException e) {
+ }
}
}
@@ -596,7 +553,13 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
* VoiceInteractor.AbortVoiceRequest.onAbortResult}.
*/
public void sendAbortResult(Bundle result) {
- sendAbortVoiceResult(result);
+ try {
+ if (DEBUG) Log.d(TAG, "sendConfirmResult: req=" + mInterface
+ + " result=" + result);
+ finishRequest();
+ mCallback.deliverAbortVoiceResult(mInterface, result);
+ } catch (RemoteException e) {
+ }
}
}
@@ -621,6 +584,18 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
return mCommand;
}
+ void sendCommandResult(boolean finished, Bundle result) {
+ try {
+ if (DEBUG) Log.d(TAG, "sendCommandResult: req=" + mInterface
+ + " result=" + result);
+ if (finished) {
+ finishRequest();
+ }
+ mCallback.deliverCommandResult(mInterface, finished, result);
+ } catch (RemoteException e) {
+ }
+ }
+
/**
* Report an intermediate result of the request, without completing it (the request
* is still active and the app is waiting for the final result), resulting in a call to
@@ -829,11 +804,10 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
}
}
- void doCreate(IVoiceInteractionManagerService service, IBinder token, Bundle args,
- int startFlags) {
+ void doCreate(IVoiceInteractionManagerService service, IBinder token) {
mSystemService = service;
mToken = token;
- onCreate(args, startFlags);
+ onCreate();
}
void doShow(Bundle args, int flags, final IVoiceInteractionSessionShowCallback showCallback) {
@@ -919,11 +893,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
mContentFrame = (FrameLayout)mRootView.findViewById(android.R.id.content);
}
- /** @hide */
- public void show() {
- show(null, 0);
- }
-
/**
* Show the UI for this session. This asks the system to go through the process of showing
* your UI, which will eventually culminate in {@link #onShow}. This is similar to calling
@@ -958,14 +927,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
}
}
- /** @hide */
- public void showWindow() {
- }
-
- /** @hide */
- public void hideWindow() {
- }
-
/**
* You can call this to customize the theme used by your IME's window.
* This must be set before {@link #onCreate}, so you
@@ -1040,6 +1001,21 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
}
/**
+ * Request that all system dialogs (and status bar shade etc) be closed, allowing
+ * access to the session's UI. This will <em>not</em> cause the lock screen to be
+ * dismissed.
+ */
+ public void closeSystemDialogs() {
+ if (mToken == null) {
+ throw new IllegalStateException("Can't call before onCreate()");
+ }
+ try {
+ mSystemService.closeSystemDialogs(mToken);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
* Convenience for inflating views.
*/
public LayoutInflater getLayoutInflater() {
@@ -1062,7 +1038,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
if (mToken == null) {
throw new IllegalStateException("Can't call before onCreate()");
}
- hideWindow();
try {
mSystemService.finish(mToken);
} catch (RemoteException e) {
@@ -1077,16 +1052,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
doOnCreate();
}
- /** @hide */
- public void onCreate(Bundle args) {
- doOnCreate();
- }
-
- /** @hide */
- public void onCreate(Bundle args, int showFlags) {
- doOnCreate();
- }
-
private void doOnCreate() {
mTheme = mTheme != 0 ? mTheme
: com.android.internal.R.style.Theme_DeviceDefault_VoiceInteractionSession;
@@ -1244,34 +1209,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
hide();
}
- /** @hide */
- public boolean[] onGetSupportedCommands(Caller caller, String[] commands) {
- return new boolean[commands.length];
- }
- /** @hide */
- public void onConfirm(Caller caller, Request request, CharSequence prompt,
- Bundle extras) {
- }
- /** @hide */
- public void onPickOption(Caller caller, Request request, CharSequence prompt,
- VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) {
- }
- /** @hide */
- public void onCompleteVoice(Caller caller, Request request, CharSequence message,
- Bundle extras) {
- request.sendCompleteVoiceResult(null);
- }
- /** @hide */
- public void onAbortVoice(Caller caller, Request request, CharSequence message, Bundle extras) {
- request.sendAbortVoiceResult(null);
- }
- /** @hide */
- public void onCommand(Caller caller, Request request, String command, Bundle extras) {
- }
- /** @hide */
- public void onCancel(Request request) {
- }
-
/**
* Request to query for what extended commands the session supports.
*
@@ -1282,7 +1219,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
* an array of all false entries.
*/
public boolean[] onGetSupportedCommands(String[] commands) {
- return onGetSupportedCommands(new Caller(), commands);
+ return new boolean[commands.length];
}
/**
@@ -1293,7 +1230,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
* @param request The active request.
*/
public void onRequestConfirmation(ConfirmationRequest request) {
- onConfirm(request, request, request.getPrompt(), request.getExtras());
}
/**
@@ -1303,8 +1239,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
* @param request The active request.
*/
public void onRequestPickOption(PickOptionRequest request) {
- onPickOption(request, request, request.getPrompt(), request.getOptions(),
- request.getExtras());
}
/**
@@ -1317,7 +1251,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
* @param request The active request.
*/
public void onRequestCompleteVoice(CompleteVoiceRequest request) {
- onCompleteVoice(request, request, request.getMessage(), request.getExtras());
}
/**
@@ -1330,7 +1263,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
* @param request The active request.
*/
public void onRequestAbortVoice(AbortVoiceRequest request) {
- onAbortVoice(request, request, request.getMessage(), request.getExtras());
}
/**
@@ -1341,11 +1273,10 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
* @param request The active request.
*/
public void onRequestCommand(CommandRequest request) {
- onCommand(request, request, request.getCommand(), request.getExtras());
}
/**
- * Called when the {@link android.app.VoiceInteractor} has asked to cancelLocked a {@link Request}
+ * Called when the {@link android.app.VoiceInteractor} has asked to cancel a {@link Request}
* that was previously delivered to {@link #onRequestConfirmation},
* {@link #onRequestPickOption}, {@link #onRequestCompleteVoice}, {@link #onRequestAbortVoice},
* or {@link #onRequestCommand}.
@@ -1353,6 +1284,5 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
* @param request The request that is being canceled.
*/
public void onCancelRequest(Request request) {
- onCancel(request);
}
}
diff --git a/core/java/android/service/voice/VoiceInteractionSessionService.java b/core/java/android/service/voice/VoiceInteractionSessionService.java
index 8f988f3..fb9f973 100644
--- a/core/java/android/service/voice/VoiceInteractionSessionService.java
+++ b/core/java/android/service/voice/VoiceInteractionSessionService.java
@@ -109,7 +109,7 @@ public abstract class VoiceInteractionSessionService extends Service {
mSession = onNewSession(args);
try {
mSystemService.deliverNewSession(token, mSession.mSession, mSession.mInteractor);
- mSession.doCreate(mSystemService, token, args, startFlags);
+ mSession.doCreate(mSystemService, token);
} catch (RemoteException e) {
}
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 8952807..d598291 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -271,8 +271,8 @@ public abstract class WallpaperService extends Service {
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
Configuration newConfig) {
- Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED,
- reportDraw ? 1 : 0);
+ Message msg = mCaller.obtainMessageIO(MSG_WINDOW_RESIZED,
+ reportDraw ? 1 : 0, outsets);
mCaller.sendMessage(msg);
}
@@ -649,7 +649,7 @@ public abstract class WallpaperService extends Service {
com.android.internal.R.style.Animation_Wallpaper;
mInputChannel = new InputChannel();
if (mSession.addToDisplay(mWindow, mWindow.mSeq, mLayout, View.VISIBLE,
- Display.DEFAULT_DISPLAY, mContentInsets, mStableInsets,
+ Display.DEFAULT_DISPLAY, mContentInsets, mStableInsets, mOutsets,
mInputChannel) < 0) {
Log.w(TAG, "Failed to add window while updating wallpaper surface.");
return;
@@ -1192,6 +1192,7 @@ public abstract class WallpaperService extends Service {
} break;
case MSG_WINDOW_RESIZED: {
final boolean reportDraw = message.arg1 != 0;
+ mEngine.mOutsets.set((Rect) message.obj);
mEngine.updateSurface(true, false, reportDraw);
mEngine.doOffsetsChanged(true);
} break;
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 3eeb04a..eae4329 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -1486,19 +1486,28 @@ public class TextToSpeech {
// Get the default voice for the locale.
String voiceName = service.getDefaultVoiceNameFor(language, country, variant);
if (TextUtils.isEmpty(voiceName)) {
- Log.w(TAG, "Couldn't find the default voice for " + language + "/" +
- country + "/" + variant);
+ Log.w(TAG, "Couldn't find the default voice for " + language + "-" +
+ country + "-" + variant);
return LANG_NOT_SUPPORTED;
}
// Load it.
if (service.loadVoice(getCallerIdentity(), voiceName) == TextToSpeech.ERROR) {
+ Log.w(TAG, "The service claimed " + language + "-" + country + "-"
+ + variant + " was available with voice name " + voiceName
+ + " but loadVoice returned ERROR");
return LANG_NOT_SUPPORTED;
}
// Set the language/country/variant of the voice, so #getLanguage will return
// the currently set voice locale when called.
Voice voice = getVoice(service, voiceName);
+ if (voice == null) {
+ Log.w(TAG, "getDefaultVoiceNameFor returned " + voiceName + " for locale "
+ + language + "-" + country + "-" + variant
+ + " but getVoice returns null");
+ return LANG_NOT_SUPPORTED;
+ }
String voiceLanguage = "";
try {
voiceLanguage = voice.getLocale().getISO3Language();
@@ -1682,6 +1691,7 @@ public class TextToSpeech {
private Voice getVoice(ITextToSpeechService service, String voiceName) throws RemoteException {
List<Voice> voices = service.getVoices();
if (voices == null) {
+ Log.w(TAG, "getVoices returned null");
return null;
}
for (Voice voice : voices) {
@@ -1689,6 +1699,7 @@ public class TextToSpeech {
return voice;
}
}
+ Log.w(TAG, "Could not find voice " + voiceName + " in voice list");
return null;
}
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index ba98f27..fa015b2 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -293,7 +293,9 @@ public abstract class TextToSpeechService extends Service {
}
Set<String> features = onGetFeaturesForLanguage(locale.getISO3Language(),
locale.getISO3Country(), locale.getVariant());
- voices.add(new Voice(locale.toLanguageTag(), locale, Voice.QUALITY_NORMAL,
+ String voiceName = onGetDefaultVoiceNameFor(locale.getISO3Language(),
+ locale.getISO3Country(), locale.getVariant());
+ voices.add(new Voice(voiceName, locale, Voice.QUALITY_NORMAL,
Voice.LATENCY_NORMAL, false, features));
}
return voices;
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 464710b..b6fa4e4c 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -714,6 +714,27 @@ public class StaticLayout extends Layout {
float[] lineWidths = lineBreaks.widths;
int[] flags = lineBreaks.flags;
+ final int remainingLineCount = mMaximumVisibleLineCount - mLineCount;
+ final boolean ellipsisMayBeApplied = ellipsize != null
+ && (ellipsize == TextUtils.TruncateAt.END
+ || (mMaximumVisibleLineCount == 1
+ && ellipsize != TextUtils.TruncateAt.MARQUEE));
+ if (remainingLineCount < breakCount && ellipsisMayBeApplied) {
+ // Treat the last line and overflowed lines as a single line.
+ breaks[remainingLineCount - 1] = breaks[breakCount - 1];
+ // Calculate width and flag.
+ float width = 0;
+ int flag = 0;
+ for (int i = remainingLineCount - 1; i < breakCount; i++) {
+ width += lineWidths[i];
+ flag |= flags[i] & TAB_MASK;
+ }
+ lineWidths[remainingLineCount - 1] = width;
+ flags[remainingLineCount - 1] = flag;
+
+ breakCount = remainingLineCount;
+ }
+
// here is the offset of the starting character of the line we are currently measuring
int here = paraStart;
diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java
index 47d5c79..82689b9 100644
--- a/core/java/android/text/format/Formatter.java
+++ b/core/java/android/text/format/Formatter.java
@@ -105,32 +105,45 @@ public final class Formatter {
mult = TrafficStats.PB_IN_BYTES;
result = result / 1024;
}
- String value;
+ // Note we calculate the rounded long by ourselves, but still let String.format()
+ // compute the rounded value. String.format("%f", 0.1) might not return "0.1" due to
+ // floating point errors.
+ final int roundFactor;
+ final String roundFormat;
if (result < 1) {
- value = String.format("%.2f", result);
+ roundFactor = 100;
+ roundFormat = "%.2f";
} else if (result < 10) {
if ((flags & FLAG_SHORTER) != 0) {
- value = String.format("%.1f", result);
+ roundFactor = 10;
+ roundFormat = "%.1f";
} else {
- value = String.format("%.2f", result);
+ roundFactor = 100;
+ roundFormat = "%.2f";
}
} else if (result < 100) {
if ((flags & FLAG_SHORTER) != 0) {
- value = String.format("%.0f", result);
+ roundFactor = 1;
+ roundFormat = "%.0f";
} else {
- value = String.format("%.2f", result);
+ roundFactor = 100;
+ roundFormat = "%.2f";
}
} else {
- value = String.format("%.0f", result);
+ roundFactor = 1;
+ roundFormat = "%.0f";
}
+ final String roundedString = String.format(roundFormat, result);
+
+ // Note this might overflow if result >= Long.MAX_VALUE / 100, but that's like 80PB so
+ // it's okay (for now)...
+ final long roundedBytes =
+ (flags & FLAG_CALCULATE_ROUNDED) == 0 ? 0
+ : (((long) Math.round(result * roundFactor)) * mult / roundFactor);
+
final String units = res.getString(suffix);
- final long roundedBytes;
- if ((flags & FLAG_CALCULATE_ROUNDED) != 0) {
- roundedBytes = (long) (Double.parseDouble(value) * mult);
- } else {
- roundedBytes = 0;
- }
- return new BytesResult(value, units, roundedBytes);
+
+ return new BytesResult(roundedString, units, roundedBytes);
}
/**
diff --git a/core/java/android/text/method/WordIterator.java b/core/java/android/text/method/WordIterator.java
index 5dda8a7..3688cfa 100644
--- a/core/java/android/text/method/WordIterator.java
+++ b/core/java/android/text/method/WordIterator.java
@@ -147,11 +147,90 @@ public class WordIterator implements Selection.PositionIterator {
* @throws IllegalArgumentException is offset is not valid.
*/
public int getBeginning(int offset) {
+ // TODO: Check if usage of this can be updated to getBeginning(offset, true) if
+ // so this method can be removed.
+ return getBeginning(offset, false);
+ }
+
+ /**
+ * If <code>offset</code> is within a word, returns the index of the last character of that
+ * word plus one, otherwise returns BreakIterator.DONE.
+ *
+ * The offsets that are considered to be part of a word are the indexes of its characters,
+ * <i>as well as</i> the index of its last character plus one.
+ * If offset is the index of a low surrogate character, BreakIterator.DONE will be returned.
+ *
+ * Valid range for offset is [0..textLength] (note the inclusive upper bound).
+ * The returned value is within [offset..textLength] or BreakIterator.DONE.
+ *
+ * @throws IllegalArgumentException is offset is not valid.
+ */
+ public int getEnd(int offset) {
+ // TODO: Check if usage of this can be updated to getEnd(offset, true), if
+ // so this method can be removed.
+ return getEnd(offset, false);
+ }
+
+ /**
+ * If the <code>offset</code> is within a word or on a word boundary that can only be
+ * considered the start of a word (e.g. _word where "_" is any character that would not
+ * be considered part of the word) then this returns the index of the first character of
+ * that word.
+ *
+ * If the offset is on a word boundary that can be considered the start and end of a
+ * word, e.g. AABB (where AA and BB are both words) and the offset is the boundary
+ * between AA and BB, this would return the start of the previous word, AA.
+ *
+ * Returns BreakIterator.DONE if there is no previous boundary.
+ *
+ * @throws IllegalArgumentException is offset is not valid.
+ */
+ public int getPrevWordBeginningOnTwoWordsBoundary(int offset) {
+ return getBeginning(offset, true);
+ }
+
+ /**
+ * If the <code>offset</code> is within a word or on a word boundary that can only be
+ * considered the end of a word (e.g. word_ where "_" is any character that would not
+ * be considered part of the word) then this returns the index of the last character
+ * plus one of that word.
+ *
+ * If the offset is on a word boundary that can be considered the start and end of a
+ * word, e.g. AABB (where AA and BB are both words) and the offset is the boundary
+ * between AA and BB, this would return the end of the next word, BB.
+ *
+ * Returns BreakIterator.DONE if there is no next boundary.
+ *
+ * @throws IllegalArgumentException is offset is not valid.
+ */
+ public int getNextWordEndOnTwoWordBoundary(int offset) {
+ return getEnd(offset, true);
+ }
+
+ /**
+ * If the <code>offset</code> is within a word or on a word boundary that can only be
+ * considered the start of a word (e.g. _word where "_" is any character that would not
+ * be considered part of the word) then this returns the index of the first character of
+ * that word.
+ *
+ * If the offset is on a word boundary that can be considered the start and end of a
+ * word, e.g. AABB (where AA and BB are both words) and the offset is the boundary
+ * between AA and BB, and getPrevWordBeginningOnTwoWordsBoundary is true then this would
+ * return the start of the previous word, AA. Otherwise it would return the current offset,
+ * the start of BB.
+ *
+ * Returns BreakIterator.DONE if there is no previous boundary.
+ *
+ * @throws IllegalArgumentException is offset is not valid.
+ */
+ private int getBeginning(int offset, boolean getPrevWordBeginningOnTwoWordsBoundary) {
final int shiftedOffset = offset - mOffsetShift;
checkOffsetIsValid(shiftedOffset);
if (isOnLetterOrDigit(shiftedOffset)) {
- if (mIterator.isBoundary(shiftedOffset)) {
+ if (mIterator.isBoundary(shiftedOffset)
+ && (!isAfterLetterOrDigit(shiftedOffset)
+ || !getPrevWordBeginningOnTwoWordsBoundary)) {
return shiftedOffset + mOffsetShift;
} else {
return mIterator.preceding(shiftedOffset) + mOffsetShift;
@@ -164,24 +243,29 @@ public class WordIterator implements Selection.PositionIterator {
return BreakIterator.DONE;
}
- /** If <code>offset</code> is within a word, returns the index of the last character of that
- * word plus one, otherwise returns BreakIterator.DONE.
+ /**
+ * If the <code>offset</code> is within a word or on a word boundary that can only be
+ * considered the end of a word (e.g. word_ where "_" is any character that would not be
+ * considered part of the word) then this returns the index of the last character plus one
+ * of that word.
*
- * The offsets that are considered to be part of a word are the indexes of its characters,
- * <i>as well as</i> the index of its last character plus one.
- * If offset is the index of a low surrogate character, BreakIterator.DONE will be returned.
+ * If the offset is on a word boundary that can be considered the start and end of a
+ * word, e.g. AABB (where AA and BB are both words) and the offset is the boundary
+ * between AA and BB, and getNextWordEndOnTwoWordBoundary is true then this would return
+ * the end of the next word, BB. Otherwise it would return the current offset, the end
+ * of AA.
*
- * Valid range for offset is [0..textLength] (note the inclusive upper bound).
- * The returned value is within [offset..textLength] or BreakIterator.DONE.
+ * Returns BreakIterator.DONE if there is no next boundary.
*
* @throws IllegalArgumentException is offset is not valid.
*/
- public int getEnd(int offset) {
+ private int getEnd(int offset, boolean getNextWordEndOnTwoWordBoundary) {
final int shiftedOffset = offset - mOffsetShift;
checkOffsetIsValid(shiftedOffset);
if (isAfterLetterOrDigit(shiftedOffset)) {
- if (mIterator.isBoundary(shiftedOffset)) {
+ if (mIterator.isBoundary(shiftedOffset)
+ && (!isOnLetterOrDigit(shiftedOffset) || !getNextWordEndOnTwoWordBoundary)) {
return shiftedOffset + mOffsetShift;
} else {
return mIterator.following(shiftedOffset) + mOffsetShift;
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index 868b262..e958058 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -528,11 +528,13 @@ public abstract class Transition implements Cloneable {
ArrayMap<View, TransitionValues> unmatchedEnd) {
for (int i = unmatchedStart.size() - 1; i >= 0; i--) {
View view = unmatchedStart.keyAt(i);
- TransitionValues end = unmatchedEnd.remove(view);
- if (end != null) {
- TransitionValues start = unmatchedStart.removeAt(i);
- mStartValuesList.add(start);
- mEndValuesList.add(end);
+ if (view != null && isValidTarget(view)) {
+ TransitionValues end = unmatchedEnd.remove(view);
+ if (end != null && end.view != null && isValidTarget(end.view)) {
+ TransitionValues start = unmatchedStart.removeAt(i);
+ mStartValuesList.add(start);
+ mEndValuesList.add(end);
+ }
}
}
}
@@ -548,9 +550,9 @@ public abstract class Transition implements Cloneable {
int numStartIds = startItemIds.size();
for (int i = 0; i < numStartIds; i++) {
View startView = startItemIds.valueAt(i);
- if (startView != null) {
+ if (startView != null && isValidTarget(startView)) {
View endView = endItemIds.get(startItemIds.keyAt(i));
- if (endView != null) {
+ if (endView != null && isValidTarget(endView)) {
TransitionValues startValues = unmatchedStart.get(startView);
TransitionValues endValues = unmatchedEnd.get(endView);
if (startValues != null && endValues != null) {
@@ -626,14 +628,20 @@ public abstract class Transition implements Cloneable {
ArrayMap<View, TransitionValues> unmatchedEnd) {
// Views that only exist in the start Scene
for (int i = 0; i < unmatchedStart.size(); i++) {
- mStartValuesList.add(unmatchedStart.valueAt(i));
- mEndValuesList.add(null);
+ final TransitionValues start = unmatchedStart.valueAt(i);
+ if (isValidTarget(start.view)) {
+ mStartValuesList.add(start);
+ mEndValuesList.add(null);
+ }
}
// Views that only exist in the end Scene
for (int i = 0; i < unmatchedEnd.size(); i++) {
- mEndValuesList.add(unmatchedEnd.valueAt(i));
- mStartValuesList.add(null);
+ final TransitionValues end = unmatchedEnd.valueAt(i);
+ if (isValidTarget(end.view)) {
+ mEndValuesList.add(end);
+ mStartValuesList.add(null);
+ }
}
}
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index 5209f90..71c8099 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -435,10 +435,11 @@ public class TransitionManager {
sPendingTransitions.remove(sceneRoot);
final ArrayList<Transition> runningTransitions = getRunningTransitions().get(sceneRoot);
- if (runningTransitions != null) {
- final int count = runningTransitions.size();
- for (int i = 0; i < count; i++) {
- final Transition transition = runningTransitions.get(i);
+ if (runningTransitions != null && !runningTransitions.isEmpty()) {
+ // Make a copy in case this is called by an onTransitionEnd listener
+ ArrayList<Transition> copy = new ArrayList(runningTransitions);
+ for (int i = copy.size() - 1; i >= 0; i--) {
+ final Transition transition = copy.get(i);
transition.end();
}
}
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index 585fc4e..f9dd7eb 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -452,6 +452,7 @@ public abstract class Visibility extends Transition {
DisappearListener disappearListener = new DisappearListener(viewToKeep,
finalVisibility, isForcedVisibility);
animator.addListener(disappearListener);
+ animator.addPauseListener(disappearListener);
addListener(disappearListener);
} else if (!isForcedVisibility) {
viewToKeep.setTransitionVisibility(originalVisibility);
diff --git a/core/java/android/util/LocalLog.java b/core/java/android/util/LocalLog.java
index cab5d19..4862f01 100644
--- a/core/java/android/util/LocalLog.java
+++ b/core/java/android/util/LocalLog.java
@@ -54,4 +54,18 @@ public final class LocalLog {
pw.println(itr.next());
}
}
+
+ public static class ReadOnlyLocalLog {
+ private final LocalLog mLog;
+ ReadOnlyLocalLog(LocalLog log) {
+ mLog = log;
+ }
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ mLog.dump(fd, pw, args);
+ }
+ }
+
+ public ReadOnlyLocalLog readOnlyLocalLog() {
+ return new ReadOnlyLocalLog(this);
+ }
}
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index 353388d..c1eb80d 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -28,6 +28,7 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
@@ -54,6 +55,8 @@ public class TimeUtils {
private static ArrayList<TimeZone> sLastUniqueZoneOffsets = null;
private static String sLastUniqueCountry = null;
+ /** {@hide} */
+ private static SimpleDateFormat sLoggingFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/**
* Tries to return a time zone that would have had the specified offset
@@ -441,4 +444,13 @@ public class TimeUtils {
return Long.toString(millis);
}
}
+
+ /** {@hide} */
+ public static String formatForLogging(long millis) {
+ if (millis <= 0) {
+ return "unknown";
+ } else {
+ return sLoggingFormat.format(new Date(millis));
+ }
+ }
}
diff --git a/core/java/android/view/ActionProvider.java b/core/java/android/view/ActionProvider.java
index c3aafde..752240f 100644
--- a/core/java/android/view/ActionProvider.java
+++ b/core/java/android/view/ActionProvider.java
@@ -237,6 +237,14 @@ public abstract class ActionProvider {
}
/**
+ * @hide
+ */
+ public void reset() {
+ mVisibilityListener = null;
+ mSubUiVisibilityListener = null;
+ }
+
+ /**
* @hide Internal use only
*/
public interface SubUiVisibilityListener {
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 19253dd..73b4a6e 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -40,7 +40,7 @@ interface IWindowSession {
out InputChannel outInputChannel);
int addToDisplay(IWindow window, int seq, in WindowManager.LayoutParams attrs,
in int viewVisibility, in int layerStackId, out Rect outContentInsets,
- out Rect outStableInsets, out InputChannel outInputChannel);
+ out Rect outStableInsets, out Rect outOutsets, out InputChannel outInputChannel);
int addWithoutInputChannel(IWindow window, int seq, in WindowManager.LayoutParams attrs,
in int viewVisibility, out Rect outContentInsets, out Rect outStableInsets);
int addToDisplayWithoutInputChannel(IWindow window, int seq, in WindowManager.LayoutParams attrs,
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index e044f1e..f6119e2 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -434,7 +434,6 @@ public class ThreadedRenderer extends HardwareRenderer {
private static class ProcessInitializer {
static ProcessInitializer sInstance = new ProcessInitializer();
- static IGraphicsStats sGraphicsStatsService;
private static IBinder sProcToken;
private boolean mInitialized = false;
@@ -449,19 +448,19 @@ public class ThreadedRenderer extends HardwareRenderer {
}
private static void initGraphicsStats(Context context, long renderProxy) {
- IBinder binder = ServiceManager.getService("graphicsstats");
- if (binder == null) return;
-
- sGraphicsStatsService = IGraphicsStats.Stub.asInterface(binder);
- sProcToken = new Binder();
try {
+ IBinder binder = ServiceManager.getService("graphicsstats");
+ if (binder == null) return;
+ IGraphicsStats graphicsStatsService = IGraphicsStats.Stub
+ .asInterface(binder);
+ sProcToken = new Binder();
final String pkg = context.getApplicationInfo().packageName;
- ParcelFileDescriptor pfd = sGraphicsStatsService.
+ ParcelFileDescriptor pfd = graphicsStatsService.
requestBufferForProcess(pkg, sProcToken);
nSetProcessStatsBuffer(renderProxy, pfd.getFd());
pfd.close();
- } catch (Exception e) {
- Log.w(LOG_TAG, "Could not acquire gfx stats buffer", e);
+ } catch (Throwable t) {
+ Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
}
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 92dae2e..63dd492 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6179,6 +6179,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
structure.setId(id, null, null, null);
}
structure.setDimens(mLeft, mTop, mScrollX, mScrollY, mRight - mLeft, mBottom - mTop);
+ if (!hasIdentityMatrix()) {
+ structure.setTransformation(getMatrix());
+ }
+ structure.setElevation(getZ());
structure.setVisibility(getVisibility());
structure.setEnabled(isEnabled());
if (isClickable()) {
@@ -6215,11 +6219,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
structure.setContentDescription(getContentDescription());
}
- /** @hide */
- public void onProvideAssistStructure(ViewStructure structure) {
- onProvideStructure(structure);
- }
-
/**
* Called when assist structure is being retrieved from a view as part of
* {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData} to
@@ -6232,7 +6231,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
if (provider != null) {
AccessibilityNodeInfo info = createAccessibilityNodeInfo();
- Log.i("View", "Provider of " + this + ": children=" + info.getChildCount());
structure.setChildCount(1);
ViewStructure root = structure.newChild(0);
populateVirtualStructure(root, provider, info);
@@ -6240,11 +6238,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
}
- /** @hide */
- public void onProvideVirtualAssistStructure(ViewStructure structure) {
- onProvideVirtualStructure(structure);
- }
-
private void populateVirtualStructure(ViewStructure structure,
AccessibilityNodeProvider provider, AccessibilityNodeInfo info) {
structure.setId(AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId()),
@@ -6284,8 +6277,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
CharSequence cname = info.getClassName();
structure.setClassName(cname != null ? cname.toString() : null);
structure.setContentDescription(info.getContentDescription());
- Log.i("View", "vassist " + cname + " @ " + rect.toShortString()
- + " text=" + info.getText() + " cd=" + info.getContentDescription());
if (info.getText() != null || info.getError() != null) {
structure.setText(info.getText(), info.getTextSelectionStart(),
info.getTextSelectionEnd());
@@ -6310,8 +6301,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void dispatchProvideStructure(ViewStructure structure) {
if (!isAssistBlocked()) {
- onProvideAssistStructure(structure);
- onProvideVirtualAssistStructure(structure);
+ onProvideStructure(structure);
+ onProvideVirtualStructure(structure);
} else {
structure.setClassName(getAccessibilityClassName().toString());
structure.setAssistBlocked(true);
@@ -8710,14 +8701,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * Adds the children of a given View for accessibility. Since some Views are
- * not important for accessibility the children for accessibility are not
- * necessarily direct children of the view, rather they are the first level of
- * descendants important for accessibility.
+ * Adds the children of this View relevant for accessibility to the given list
+ * as output. Since some Views are not important for accessibility the added
+ * child views are not necessarily direct children of this view, rather they are
+ * the first level of descendants important for accessibility.
*
- * @param children The list of children for accessibility.
+ * @param outChildren The output list that will receive children for accessibility.
*/
- public void addChildrenForAccessibility(ArrayList<View> children) {
+ public void addChildrenForAccessibility(ArrayList<View> outChildren) {
}
@@ -12297,6 +12288,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mRenderNode.offsetTopAndBottom(offset);
if (isHardwareAccelerated()) {
invalidateViewProperty(false, false);
+ invalidateParentIfNeededAndWasQuickRejected();
} else {
if (!matrixIsIdentity) {
invalidateViewProperty(false, true);
@@ -12344,6 +12336,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mRenderNode.offsetLeftAndRight(offset);
if (isHardwareAccelerated()) {
invalidateViewProperty(false, false);
+ invalidateParentIfNeededAndWasQuickRejected();
} else {
if (!matrixIsIdentity) {
invalidateViewProperty(false, true);
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 2e2ba88..6dca26b 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1919,7 +1919,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
@Override
- public void addChildrenForAccessibility(ArrayList<View> childrenForAccessibility) {
+ public void addChildrenForAccessibility(ArrayList<View> outChildren) {
if (getAccessibilityNodeProvider() != null) {
return;
}
@@ -1930,9 +1930,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
View child = children.getChildAt(i);
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
if (child.includeForAccessibility()) {
- childrenForAccessibility.add(child);
+ outChildren.add(child);
} else {
- child.addChildrenForAccessibility(childrenForAccessibility);
+ child.addChildrenForAccessibility(outChildren);
}
}
}
@@ -3236,13 +3236,15 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
for (int i = 0; i < getChildCount(); i++) {
View c = getChildAt(i);
- Insets insets = c.getOpticalInsets();
-
- drawRect(canvas, paint,
- c.getLeft() + insets.left,
- c.getTop() + insets.top,
- c.getRight() - insets.right - 1,
- c.getBottom() - insets.bottom - 1);
+ if (c.getVisibility() != View.GONE) {
+ Insets insets = c.getOpticalInsets();
+
+ drawRect(canvas, paint,
+ c.getLeft() + insets.left,
+ c.getTop() + insets.top,
+ c.getRight() - insets.right - 1,
+ c.getBottom() - insets.bottom - 1);
+ }
}
}
@@ -3263,8 +3265,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
int lineWidth = dipsToPixels(1);
for (int i = 0; i < getChildCount(); i++) {
View c = getChildAt(i);
- drawRectCorners(canvas, c.getLeft(), c.getTop(), c.getRight(), c.getBottom(),
- paint, lineLength, lineWidth);
+ if (c.getVisibility() != View.GONE) {
+ drawRectCorners(canvas, c.getLeft(), c.getTop(), c.getRight(), c.getBottom(),
+ paint, lineLength, lineWidth);
+ }
}
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 8b57d96..6d0d788 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -531,7 +531,8 @@ public final class ViewRootImpl implements ViewParent,
collectViewAttributes();
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
- mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, mInputChannel);
+ mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
+ mAttachInfo.mOutsets, mInputChannel);
} catch (RemoteException e) {
mAdded = false;
mView = null;
@@ -1590,6 +1591,7 @@ public final class ViewRootImpl implements ViewParent,
+ " content=" + mPendingContentInsets.toShortString()
+ " visible=" + mPendingVisibleInsets.toShortString()
+ " visible=" + mPendingStableInsets.toShortString()
+ + " outsets=" + mPendingOutsets.toShortString()
+ " surface=" + mSurface);
if (mPendingConfiguration.seq != 0) {
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 9ab0ace..794622a 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -16,6 +16,7 @@
package android.view;
+import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.Bundle;
@@ -50,6 +51,28 @@ public abstract class ViewStructure {
int height);
/**
+ * Set the transformation matrix associated with this view, as per
+ * {@link View#getMatrix View.getMatrix()}, or null if there is none.
+ */
+ public abstract void setTransformation(Matrix matrix);
+
+ /**
+ * Set the visual elevation (shadow) of the view, as per
+ * {@link View#getZ View.getZ()}. Note this is <em>not</em> related
+ * to the physical Z-ordering of this view relative to its other siblings (that is how
+ * they overlap when drawing), it is only the visual representation for shadowing.
+ */
+ public abstract void setElevation(float elevation);
+
+ /**
+ * Set an alpha transformation that is applied to this view, as per
+ * {@link View#getAlpha View.getAlpha()}. Value ranges from 0
+ * (completely transparent) to 1 (completely opaque); the default is 1, which means
+ * no transformation.
+ */
+ public abstract void setAlpha(float alpha);
+
+ /**
* Set the visibility state of this view, as per
* {@link View#getVisibility View.getVisibility()}.
*/
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index ca5f5ad..64210ea 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -879,13 +879,15 @@ public interface WindowManagerPolicy {
* be correct.
*
* @param attrs The LayoutParams of the window.
+ * @param rotation Rotation of the display.
* @param outContentInsets The areas covered by system windows, expressed as positive insets.
* @param outStableInsets The areas covered by stable system windows irrespective of their
* current visibility. Expressed as positive insets.
+ * @param outOutsets The areas that are not real display, but we would like to treat as such.
*
*/
- public void getInsetHintLw(WindowManager.LayoutParams attrs, Rect outContentInsets,
- Rect outStableInsets);
+ public void getInsetHintLw(WindowManager.LayoutParams attrs, int rotation,
+ Rect outContentInsets, Rect outStableInsets, Rect outOutsets);
/**
* Called when layout of the windows is finished. After this function has
@@ -913,12 +915,13 @@ public interface WindowManagerPolicy {
/**
* Called following layout of all window to apply policy to each window.
- *
+ *
* @param win The window being positioned.
- * @param attrs The LayoutParams of the window.
+ * @param attrs The LayoutParams of the window.
+ * @param attached For sub-windows, the window it is attached to. Otherwise null.
*/
public void applyPostLayoutPolicyLw(WindowState win,
- WindowManager.LayoutParams attrs);
+ WindowManager.LayoutParams attrs, WindowState attached);
/**
* Called following layout of all windows and after policy has been applied
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 87706ef..1464bb5 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -689,6 +689,11 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
public static final int TYPE_VIEW_CONTEXT_CLICKED = 0x00800000;
/**
+ * Represents the event of the assistant currently reading the users screen context.
+ */
+ public static final int TYPE_ASSIST_READING_CONTEXT = 0x01000000;
+
+ /**
* Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
* The type of change is not defined.
*/
@@ -1414,6 +1419,13 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
builder.append("TYPE_VIEW_CONTEXT_CLICKED");
eventTypeCount++;
}
+ case TYPE_ASSIST_READING_CONTEXT: {
+ if (eventTypeCount > 0) {
+ builder.append(", ");
+ }
+ builder.append("TYPE_ASSIST_READING_CONTEXT");
+ eventTypeCount++;
+ }
break;
}
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index a96bf71..8bf6992 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -6605,6 +6605,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
void addScrapView(View scrap, int position) {
final AbsListView.LayoutParams lp = (AbsListView.LayoutParams) scrap.getLayoutParams();
if (lp == null) {
+ // Can't recycle, skip the scrap heap.
+ getSkippedScrap().add(scrap);
return;
}
@@ -6614,6 +6616,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
// should otherwise not be recycled.
final int viewType = lp.viewType;
if (!shouldRecycleViewType(viewType)) {
+ // Can't recycle, skip the scrap heap.
+ getSkippedScrap().add(scrap);
return;
}
@@ -6633,22 +6637,19 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
// If the adapter has stable IDs, we can reuse the view for
// the same data.
if (mTransientStateViewsById == null) {
- mTransientStateViewsById = new LongSparseArray<View>();
+ mTransientStateViewsById = new LongSparseArray<>();
}
mTransientStateViewsById.put(lp.itemId, scrap);
} else if (!mDataChanged) {
// If the data hasn't changed, we can reuse the views at
// their old positions.
if (mTransientStateViews == null) {
- mTransientStateViews = new SparseArray<View>();
+ mTransientStateViews = new SparseArray<>();
}
mTransientStateViews.put(position, scrap);
} else {
// Otherwise, we'll have to remove the view and start over.
- if (mSkippedScrap == null) {
- mSkippedScrap = new ArrayList<View>();
- }
- mSkippedScrap.add(scrap);
+ getSkippedScrap().add(scrap);
}
} else {
if (mViewTypeCount == 1) {
@@ -6663,6 +6664,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
+ private ArrayList<View> getSkippedScrap() {
+ if (mSkippedScrap == null) {
+ mSkippedScrap = new ArrayList<>();
+ }
+ return mSkippedScrap;
+ }
+
/**
* Finish the removal of any views that skipped the scrap heap.
*/
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index bb4a948..c54b28d 100644
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -553,7 +553,8 @@ public class AppSecurityPermissions {
int existingReqFlags) {
final int base = pInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
final boolean isNormal = (base == PermissionInfo.PROTECTION_NORMAL);
- final boolean isDangerous = (base == PermissionInfo.PROTECTION_DANGEROUS);
+ final boolean isDangerous = (base == PermissionInfo.PROTECTION_DANGEROUS)
+ || ((pInfo.protectionLevel&PermissionInfo.PROTECTION_FLAG_PRE23) != 0);
final boolean isRequired =
((newReqFlags&PackageInfo.REQUESTED_PERMISSION_REQUIRED) != 0);
final boolean isDevelopment =
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index 770077d..602e1ab 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -245,6 +245,17 @@ public abstract class CompoundButton extends Button implements Checkable {
}
/**
+ * @hide
+ */
+ @Override
+ public void onResolveDrawables(@ResolvedLayoutDir int layoutDirection) {
+ super.onResolveDrawables(layoutDirection);
+ if (mButtonDrawable != null) {
+ mButtonDrawable.setLayoutDirection(layoutDirection);
+ }
+ }
+
+ /**
* @return the drawable used as the compound button image
* @see #setButtonDrawable(Drawable)
* @see #setButtonDrawable(int)
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 48e69a1..1158d1e 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -38,7 +38,6 @@ import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
-import android.inputmethodservice.ExtractEditText;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcel;
@@ -70,6 +69,7 @@ import android.text.style.TextAppearanceSpan;
import android.text.style.URLSpan;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.SparseArray;
import android.view.ActionMode;
import android.view.ActionMode.Callback;
import android.view.DisplayListCanvas;
@@ -89,6 +89,7 @@ import android.view.ViewGroup.LayoutParams;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.EditorInfo;
@@ -102,6 +103,7 @@ import android.widget.TextView.OnEditorActionListener;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.GrowingArrayUtils;
+import com.android.internal.util.Preconditions;
import com.android.internal.widget.EditableInputConnection;
import java.text.BreakIterator;
@@ -110,6 +112,7 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
+
/**
* Helper class used by TextView to handle editable text views.
*
@@ -123,6 +126,7 @@ public class Editor {
private static final float[] TEMP_POSITION = new float[2];
private static int DRAG_SHADOW_MAX_TEXT_LENGTH = 20;
private static final float LINE_SLOP_MULTIPLIER_FOR_HANDLEVIEWS = 0.5f;
+ private static final int UNSET_X_VALUE = -1;
// Tag used when the Editor maintains its own separate UndoManager.
private static final String UNDO_OWNER_TAG = "Editor";
@@ -243,6 +247,8 @@ public class Editor {
private TextView mTextView;
+ final ProcessTextIntentActionsHandler mProcessTextIntentActionsHandler;
+
final CursorAnchorInfoNotifier mCursorAnchorInfoNotifier = new CursorAnchorInfoNotifier();
private final Runnable mShowFloatingToolbar = new Runnable() {
@@ -260,6 +266,7 @@ public class Editor {
mTextView = textView;
// Synchronize the filter list, which places the undo input filter at the end.
mTextView.setFilters(mTextView.getFilters());
+ mProcessTextIntentActionsHandler = new ProcessTextIntentActionsHandler(this);
}
ParcelableParcel saveInstanceState() {
@@ -735,7 +742,7 @@ public class Editor {
retOffset = getWordIteratorWithText().getPunctuationBeginning(offset);
} else {
// Not on a punctuation boundary, find the word start.
- retOffset = getWordIteratorWithText().getBeginning(offset);
+ retOffset = getWordIteratorWithText().getPrevWordBeginningOnTwoWordsBoundary(offset);
}
if (retOffset == BreakIterator.DONE) {
return offset;
@@ -750,7 +757,7 @@ public class Editor {
retOffset = getWordIteratorWithText().getPunctuationEnd(offset);
} else {
// Not on a punctuation boundary, find the word end.
- retOffset = getWordIteratorWithText().getEnd(offset);
+ retOffset = getWordIteratorWithText().getNextWordEndOnTwoWordBoundary(offset);
}
if (retOffset == BreakIterator.DONE) {
return offset;
@@ -1185,7 +1192,7 @@ public class Editor {
final InputMethodManager imm = InputMethodManager.peekInstance();
final boolean immFullScreen = (imm != null && imm.isFullscreenMode());
if (mSelectionModifierCursorController != null && mTextView.hasSelection()
- && !immFullScreen) {
+ && !immFullScreen && mTextActionMode != null) {
mSelectionModifierCursorController.show();
}
} else {
@@ -3156,7 +3163,9 @@ public class Editor {
}
}
- addIntentMenuItemsForTextProcessing(menu);
+ if (mTextView.canProcessText()) {
+ mProcessTextIntentActionsHandler.onInitializeMenu(menu);
+ }
if (menu.hasVisibleItems() || mode.getCustomView() != null) {
mTextView.setHasTransientState(true);
@@ -3204,34 +3213,6 @@ public class Editor {
updateReplaceItem(menu);
}
- private void addIntentMenuItemsForTextProcessing(Menu menu) {
- if (mTextView.canProcessText()) {
- PackageManager packageManager = mTextView.getContext().getPackageManager();
- List<ResolveInfo> supportedActivities =
- packageManager.queryIntentActivities(createProcessTextIntent(), 0);
- for (int i = 0; i < supportedActivities.size(); ++i) {
- ResolveInfo info = supportedActivities.get(i);
- menu.add(Menu.NONE, Menu.NONE,
- MENU_ITEM_ORDER_PROCESS_TEXT_INTENT_ACTIONS_START + i,
- info.loadLabel(packageManager))
- .setIntent(createProcessTextIntentForResolveInfo(info))
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
- }
- }
- }
-
- private Intent createProcessTextIntent() {
- return new Intent()
- .setAction(Intent.ACTION_PROCESS_TEXT)
- .setType("text/plain");
- }
-
- private Intent createProcessTextIntentForResolveInfo(ResolveInfo info) {
- return createProcessTextIntent()
- .putExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, !mTextView.isTextEditable())
- .setClassName(info.activityInfo.packageName, info.activityInfo.name);
- }
-
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
updateSelectAllItem(menu);
@@ -3270,12 +3251,7 @@ public class Editor {
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
- if (item.getIntent() != null
- && item.getIntent().getAction().equals(Intent.ACTION_PROCESS_TEXT)) {
- item.getIntent().putExtra(Intent.EXTRA_PROCESS_TEXT, mTextView.getSelectedText());
- mPreserveDetachedSelection = true;
- mTextView.startActivityForResult(
- item.getIntent(), TextView.PROCESS_TEXT_REQUEST_CODE);
+ if (mProcessTextIntentActionsHandler.performMenuItemAction(item)) {
return true;
}
Callback customCallback = getCustomCallback();
@@ -4067,6 +4043,10 @@ public class Editor {
private boolean mInWord = false;
// Difference between touch position and word boundary position.
private float mTouchWordDelta;
+ // X value of the previous updatePosition call.
+ private float mPrevX;
+ // Indicates if the handle has moved a boundary between LTR and RTL text.
+ private boolean mLanguageDirectionChanged = false;
public SelectionStartHandleView(Drawable drawableLtr, Drawable drawableRtl) {
super(drawableLtr, drawableRtl);
@@ -4127,13 +4107,56 @@ public class Editor {
int end = getWordEnd(offset);
int start = getWordStart(offset);
- if (offset < mPreviousOffset) {
+ if (mPrevX == UNSET_X_VALUE) {
+ mPrevX = x;
+ }
+
+ final int selectionStart = mTextView.getSelectionStart();
+ final boolean selectionStartRtl = layout.isRtlCharAt(selectionStart);
+ final boolean atRtl = layout.isRtlCharAt(offset);
+ final boolean isLvlBoundary = layout.isLevelBoundary(offset);
+ boolean isExpanding;
+
+ // We can't determine if the user is expanding or shrinking the selection if they're
+ // on a bi-di boundary, so until they've moved past the boundary we'll just place
+ // the cursor at the current position.
+ if (isLvlBoundary || (selectionStartRtl && !atRtl) || (!selectionStartRtl && atRtl)) {
+ // We're on a boundary or this is the first direction change -- just update
+ // to the current position.
+ mLanguageDirectionChanged = true;
+ mTouchWordDelta = 0.0f;
+ positionAtCursorOffset(offset, false);
+ return;
+ } else if (mLanguageDirectionChanged && !isLvlBoundary) {
+ // We've just moved past the boundary so update the position. After this we can
+ // figure out if the user is expanding or shrinking to go by word or character.
+ positionAtCursorOffset(offset, false);
+ mTouchWordDelta = 0.0f;
+ mLanguageDirectionChanged = false;
+ return;
+ } else {
+ final float xDiff = x - mPrevX;
+ if (atRtl) {
+ isExpanding = xDiff > 0 || currLine > mPrevLine;
+ } else {
+ isExpanding = xDiff < 0 || currLine < mPrevLine;
+ }
+ }
+
+ if (isExpanding) {
// User is increasing the selection.
if (!mInWord || currLine < mPrevLine) {
- // We're not in a word, or we're on a different line so we'll expand by
- // word. First ensure the user has at least entered the next word.
- int offsetToWord = Math.min((end - start) / 2, 2);
- if (offset <= end - offsetToWord || currLine < mPrevLine) {
+ // Sometimes words can be broken across lines (Chinese, hyphenation).
+ // We still snap to the start of the word but we only use the letters on the
+ // current line to determine if the user is far enough into the word to snap.
+ int wordStartOnCurrLine = start;
+ if (layout != null && layout.getLineForOffset(start) != currLine) {
+ wordStartOnCurrLine = layout.getLineStart(currLine);
+ }
+ int offsetThresholdToSnap = end - ((end - wordStartOnCurrLine) / 2);
+ if (offset <= offsetThresholdToSnap || currLine < mPrevLine) {
+ // User is far enough into the word or on a different
+ // line so we expand by word.
offset = start;
} else {
offset = mPreviousOffset;
@@ -4182,6 +4205,7 @@ public class Editor {
}
positionAtCursorOffset(offset, false);
}
+ mPrevX = x;
}
@Override
@@ -4196,6 +4220,7 @@ public class Editor {
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
// Reset the touch word offset when the user has lifted their finger.
mTouchWordDelta = 0.0f;
+ mPrevX = UNSET_X_VALUE;
}
return superResult;
}
@@ -4206,6 +4231,10 @@ public class Editor {
private boolean mInWord = false;
// Difference between touch position and word boundary position.
private float mTouchWordDelta;
+ // X value of the previous updatePosition call.
+ private float mPrevX;
+ // Indicates if the handle has moved a boundary between LTR and RTL text.
+ private boolean mLanguageDirectionChanged = false;
public SelectionEndHandleView(Drawable drawableLtr, Drawable drawableRtl) {
super(drawableLtr, drawableRtl);
@@ -4266,13 +4295,56 @@ public class Editor {
int end = getWordEnd(offset);
int start = getWordStart(offset);
- if (offset > mPreviousOffset) {
+ if (mPrevX == UNSET_X_VALUE) {
+ mPrevX = x;
+ }
+
+ final int selectionEnd = mTextView.getSelectionEnd();
+ final boolean selectionEndRtl = layout.isRtlCharAt(selectionEnd);
+ final boolean atRtl = layout.isRtlCharAt(offset);
+ final boolean isLvlBoundary = layout.isLevelBoundary(offset);
+ boolean isExpanding;
+
+ // We can't determine if the user is expanding or shrinking the selection if they're
+ // on a bi-di boundary, so until they've moved past the boundary we'll just place
+ // the cursor at the current position.
+ if (isLvlBoundary || (selectionEndRtl && !atRtl) || (!selectionEndRtl && atRtl)) {
+ // We're on a boundary or this is the first direction change -- just update
+ // to the current position.
+ mLanguageDirectionChanged = true;
+ mTouchWordDelta = 0.0f;
+ positionAtCursorOffset(offset, false);
+ return;
+ } else if (mLanguageDirectionChanged && !isLvlBoundary) {
+ // We've just moved past the boundary so update the position. After this we can
+ // figure out if the user is expanding or shrinking to go by word or character.
+ positionAtCursorOffset(offset, false);
+ mTouchWordDelta = 0.0f;
+ mLanguageDirectionChanged = false;
+ return;
+ } else {
+ final float xDiff = x - mPrevX;
+ if (atRtl) {
+ isExpanding = xDiff < 0 || currLine < mPrevLine;
+ } else {
+ isExpanding = xDiff > 0 || currLine > mPrevLine;
+ }
+ }
+
+ if (isExpanding) {
// User is increasing the selection.
if (!mInWord || currLine > mPrevLine) {
- // We're not in a word, or we're on a different line so we'll expand by
- // word. First ensure the user has at least entered the next word.
- int midPoint = Math.min((end - start) / 2, 2);
- if (offset >= start + midPoint || currLine > mPrevLine) {
+ // Sometimes words can be broken across lines (Chinese, hyphenation).
+ // We still snap to the end of the word but we only use the letters on the
+ // current line to determine if the user is far enough into the word to snap.
+ int wordEndOnCurrLine = end;
+ if (layout != null && layout.getLineForOffset(end) != currLine) {
+ wordEndOnCurrLine = layout.getLineEnd(currLine);
+ }
+ final int offsetThresholdToSnap = start + ((wordEndOnCurrLine - start) / 2);
+ if (offset >= offsetThresholdToSnap || currLine > mPrevLine) {
+ // User is far enough into the word or on a different
+ // line so we expand by word.
offset = end;
} else {
offset = mPreviousOffset;
@@ -4321,6 +4393,7 @@ public class Editor {
}
positionAtCursorOffset(offset, false);
}
+ mPrevX = x;
}
@Override
@@ -4335,6 +4408,7 @@ public class Editor {
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
// Reset the touch word offset when the user has lifted their finger.
mTouchWordDelta = 0.0f;
+ mPrevX = UNSET_X_VALUE;
}
return superResult;
}
@@ -5367,4 +5441,119 @@ public class Editor {
}
};
}
+
+ /**
+ * A helper for enabling and handling "PROCESS_TEXT" menu actions.
+ * These allow external applications to plug into currently selected text.
+ */
+ static final class ProcessTextIntentActionsHandler {
+
+ private final Editor mEditor;
+ private final TextView mTextView;
+ private final PackageManager mPackageManager;
+ private final SparseArray<Intent> mAccessibilityIntents = new SparseArray<Intent>();
+ private final SparseArray<AccessibilityNodeInfo.AccessibilityAction> mAccessibilityActions
+ = new SparseArray<AccessibilityNodeInfo.AccessibilityAction>();
+
+ private ProcessTextIntentActionsHandler(Editor editor) {
+ mEditor = Preconditions.checkNotNull(editor);
+ mTextView = Preconditions.checkNotNull(mEditor.mTextView);
+ mPackageManager = Preconditions.checkNotNull(
+ mTextView.getContext().getPackageManager());
+ }
+
+ /**
+ * Adds "PROCESS_TEXT" menu items to the specified menu.
+ */
+ public void onInitializeMenu(Menu menu) {
+ int i = 0;
+ for (ResolveInfo resolveInfo : getSupportedActivities()) {
+ menu.add(Menu.NONE, Menu.NONE,
+ Editor.MENU_ITEM_ORDER_PROCESS_TEXT_INTENT_ACTIONS_START + i++,
+ getLabel(resolveInfo))
+ .setIntent(createProcessTextIntentForResolveInfo(resolveInfo))
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+ }
+ }
+
+ /**
+ * Performs a "PROCESS_TEXT" action if there is one associated with the specified
+ * menu item.
+ *
+ * @return True if the action was performed, false otherwise.
+ */
+ public boolean performMenuItemAction(MenuItem item) {
+ return fireIntent(item.getIntent());
+ }
+
+ /**
+ * Initializes and caches "PROCESS_TEXT" accessibility actions.
+ */
+ public void initializeAccessibilityActions() {
+ mAccessibilityIntents.clear();
+ mAccessibilityActions.clear();
+ int i = 0;
+ for (ResolveInfo resolveInfo : getSupportedActivities()) {
+ int actionId = TextView.ACCESSIBILITY_ACTION_PROCESS_TEXT_START_ID + i++;
+ mAccessibilityActions.put(
+ actionId,
+ new AccessibilityNodeInfo.AccessibilityAction(
+ actionId, getLabel(resolveInfo)));
+ mAccessibilityIntents.put(
+ actionId, createProcessTextIntentForResolveInfo(resolveInfo));
+ }
+ }
+
+ /**
+ * Adds "PROCESS_TEXT" accessibility actions to the specified accessibility node info.
+ * NOTE: This needs a prior call to {@link #initializeAccessibilityActions()} to make the
+ * latest accessibility actions available for this call.
+ */
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo nodeInfo) {
+ for (int i = 0; i < mAccessibilityActions.size(); i++) {
+ nodeInfo.addAction(mAccessibilityActions.valueAt(i));
+ }
+ }
+
+ /**
+ * Performs a "PROCESS_TEXT" action if there is one associated with the specified
+ * accessibility action id.
+ *
+ * @return True if the action was performed, false otherwise.
+ */
+ public boolean performAccessibilityAction(int actionId) {
+ return fireIntent(mAccessibilityIntents.get(actionId));
+ }
+
+ private boolean fireIntent(Intent intent) {
+ if (intent != null && Intent.ACTION_PROCESS_TEXT.equals(intent.getAction())) {
+ intent.putExtra(Intent.EXTRA_PROCESS_TEXT, mTextView.getSelectedText());
+ mEditor.mPreserveDetachedSelection = true;
+ mTextView.startActivityForResult(intent, TextView.PROCESS_TEXT_REQUEST_CODE);
+ return true;
+ }
+ return false;
+ }
+
+ private List<ResolveInfo> getSupportedActivities() {
+ PackageManager packageManager = mTextView.getContext().getPackageManager();
+ return packageManager.queryIntentActivities(createProcessTextIntent(), 0);
+ }
+
+ private Intent createProcessTextIntentForResolveInfo(ResolveInfo info) {
+ return createProcessTextIntent()
+ .putExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, !mTextView.isTextEditable())
+ .setClassName(info.activityInfo.packageName, info.activityInfo.name);
+ }
+
+ private Intent createProcessTextIntent() {
+ return new Intent()
+ .setAction(Intent.ACTION_PROCESS_TEXT)
+ .setType("text/plain");
+ }
+
+ private CharSequence getLabel(ResolveInfo resolveInfo) {
+ return resolveInfo.loadLabel(mPackageManager);
+ }
+ }
}
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index e0b2395..a1582f2 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -423,14 +423,14 @@ public class ImageView extends View {
*
* <p class="note">This does Bitmap reading and decoding on the UI
* thread, which can cause a latency hiccup. If that's a concern,
- * consider using {@link #setImageDrawable(android.graphics.drawable.Drawable)} or
+ * consider using {@link #setImageDrawable(Drawable)} or
* {@link #setImageBitmap(android.graphics.Bitmap)} and
* {@link android.graphics.BitmapFactory} instead.</p>
*
- * @param uri The Uri of an image
+ * @param uri the Uri of an image, or {@code null} to clear the content
*/
@android.view.RemotableViewMethod
- public void setImageURI(Uri uri) {
+ public void setImageURI(@Nullable Uri uri) {
if (mResource != 0 ||
(mUri != uri &&
(uri == null || mUri == null || !uri.equals(mUri)))) {
@@ -453,9 +453,10 @@ public class ImageView extends View {
/**
* Sets a drawable as the content of this ImageView.
*
- * @param drawable The drawable to set
+ * @param drawable the Drawable to set, or {@code null} to clear the
+ * content
*/
- public void setImageDrawable(Drawable drawable) {
+ public void setImageDrawable(@Nullable Drawable drawable) {
if (mDrawable != drawable) {
mResource = 0;
mUri = null;
@@ -475,16 +476,19 @@ public class ImageView extends View {
/**
* Sets the content of this ImageView to the specified Icon.
*
- * <p class="note">Depending on the Icon type, this may do Bitmap reading and decoding
- * on the UI thread, which can cause UI jank. If that's a concern, consider using
+ * <p class="note">Depending on the Icon type, this may do Bitmap reading
+ * and decoding on the UI thread, which can cause UI jank. If that's a
+ * concern, consider using
* {@link Icon#loadDrawableAsync(Context, Icon.OnDrawableLoadedListener, Handler)}
- * and then {@link #setImageDrawable(android.graphics.drawable.Drawable)} instead.</p>
+ * and then {@link #setImageDrawable(android.graphics.drawable.Drawable)}
+ * instead.</p>
*
- * @param icon an Icon holding the desired image
+ * @param icon an Icon holding the desired image, or {@code null} to clear
+ * the content
*/
@android.view.RemotableViewMethod
- public void setImageIcon(Icon icon) {
- setImageDrawable(icon.loadDrawable(mContext));
+ public void setImageIcon(@Nullable Icon icon) {
+ setImageDrawable(icon == null ? null : icon.loadDrawable(mContext));
}
/**
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 056323d..b5e08ca 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -359,7 +359,7 @@ public class LinearLayout extends ViewGroup {
}
if (hasDividerBeforeChildAt(count)) {
- final View child = getVirtualChildAt(count - 1);
+ final View child = getLastNonGoneChild();
int bottom = 0;
if (child == null) {
bottom = getHeight() - getPaddingBottom() - mDividerHeight;
@@ -371,6 +371,20 @@ public class LinearLayout extends ViewGroup {
}
}
+ /**
+ * Finds the last child that is not gone. The last child will be used as the reference for
+ * where the end divider should be drawn.
+ */
+ private View getLastNonGoneChild() {
+ for (int i = getVirtualChildCount() - 1; i >= 0; i--) {
+ View child = getVirtualChildAt(i);
+ if (child != null && child.getVisibility() != GONE) {
+ return child;
+ }
+ }
+ return null;
+ }
+
void drawDividersHorizontal(Canvas canvas) {
final int count = getVirtualChildCount();
final boolean isLayoutRtl = isLayoutRtl();
@@ -392,7 +406,7 @@ public class LinearLayout extends ViewGroup {
}
if (hasDividerBeforeChildAt(count)) {
- final View child = getVirtualChildAt(count - 1);
+ final View child = getLastNonGoneChild();
int position;
if (child == null) {
if (isLayoutRtl) {
@@ -627,21 +641,30 @@ public class LinearLayout extends ViewGroup {
* @hide Pending API consideration. Currently only used internally by the system.
*/
protected boolean hasDividerBeforeChildAt(int childIndex) {
- if (childIndex == 0) {
- return (mShowDividers & SHOW_DIVIDER_BEGINNING) != 0;
- } else if (childIndex == getChildCount()) {
+ if (childIndex == getVirtualChildCount()) {
+ // Check whether the end divider should draw.
return (mShowDividers & SHOW_DIVIDER_END) != 0;
- } else if ((mShowDividers & SHOW_DIVIDER_MIDDLE) != 0) {
- boolean hasVisibleViewBefore = false;
- for (int i = childIndex - 1; i >= 0; i--) {
- if (getChildAt(i).getVisibility() != GONE) {
- hasVisibleViewBefore = true;
- break;
- }
+ }
+ boolean allViewsAreGoneBefore = allViewsAreGoneBefore(childIndex);
+ if (allViewsAreGoneBefore) {
+ // This is the first view that's not gone, check if beginning divider is enabled.
+ return (mShowDividers & SHOW_DIVIDER_BEGINNING) != 0;
+ } else {
+ return (mShowDividers & SHOW_DIVIDER_MIDDLE) != 0;
+ }
+ }
+
+ /**
+ * Checks whether all (virtual) child views before the given index are gone.
+ */
+ private boolean allViewsAreGoneBefore(int childIndex) {
+ for (int i = childIndex - 1; i >= 0; i--) {
+ View child = getVirtualChildAt(i);
+ if (child != null && child.getVisibility() != GONE) {
+ return false;
}
- return hasVisibleViewBefore;
}
- return false;
+ return true;
}
/**
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index fd0395a..9568492 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1143,8 +1143,8 @@ public class ListView extends AbsListView {
// Sets up mListPadding
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- int widthMode = MeasureSpec.getMode(widthMeasureSpec);
- int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+ final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+ final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
@@ -1153,10 +1153,12 @@ public class ListView extends AbsListView {
int childState = 0;
mItemCount = mAdapter == null ? 0 : mAdapter.getCount();
- if (mItemCount > 0 && (widthMode == MeasureSpec.UNSPECIFIED ||
- heightMode == MeasureSpec.UNSPECIFIED)) {
+ if (mItemCount > 0 && (widthMode == MeasureSpec.UNSPECIFIED
+ || heightMode == MeasureSpec.UNSPECIFIED)) {
final View child = obtainView(0, mIsScrap);
+ // Lay out child directly against the parent measure spec so that
+ // we can obtain exected minimum width and height.
measureScrapChild(child, 0, widthMeasureSpec, heightSize);
childWidth = child.getMeasuredWidth();
@@ -1173,7 +1175,7 @@ public class ListView extends AbsListView {
widthSize = mListPadding.left + mListPadding.right + childWidth +
getVerticalScrollbarWidth();
} else {
- widthSize |= (childState&MEASURED_STATE_MASK);
+ widthSize |= (childState & MEASURED_STATE_MASK);
}
if (heightMode == MeasureSpec.UNSPECIFIED) {
@@ -1186,8 +1188,9 @@ public class ListView extends AbsListView {
heightSize = measureHeightOfChildren(widthMeasureSpec, 0, NO_POSITION, heightSize, -1);
}
- setMeasuredDimension(widthSize , heightSize);
- mWidthMeasureSpec = widthMeasureSpec;
+ setMeasuredDimension(widthSize, heightSize);
+
+ mWidthMeasureSpec = widthMeasureSpec;
}
private void measureScrapChild(View child, int position, int widthMeasureSpec, int heightHint) {
@@ -1199,16 +1202,20 @@ public class ListView extends AbsListView {
p.viewType = mAdapter.getItemViewType(position);
p.forceAdd = true;
- int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,
+ final int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,
mListPadding.left + mListPadding.right, p.width);
- int lpHeight = p.height;
- int childHeightSpec;
+ final int lpHeight = p.height;
+ final int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeSafeMeasureSpec(heightHint, MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
+
+ // Since this view was measured directly aginst the parent measure
+ // spec, we must measure it again before reuse.
+ child.forceLayout();
}
/**
@@ -1248,8 +1255,7 @@ public class ListView extends AbsListView {
* @return The height of this ListView with the given children.
*/
final int measureHeightOfChildren(int widthMeasureSpec, int startPosition, int endPosition,
- final int maxHeight, int disallowPartialChildPosition) {
-
+ int maxHeight, int disallowPartialChildPosition) {
final ListAdapter adapter = mAdapter;
if (adapter == null) {
return mListPadding.top + mListPadding.bottom;
@@ -1907,8 +1913,8 @@ public class ListView extends AbsListView {
}
p.viewType = mAdapter.getItemViewType(position);
- if ((recycled && !p.forceAdd) || (p.recycledHeaderFooter &&
- p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) {
+ if ((recycled && !p.forceAdd) || (p.recycledHeaderFooter
+ && p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) {
attachViewToParent(child, flowDown ? -1 : 0, p);
} else {
p.forceAdd = false;
@@ -1936,10 +1942,10 @@ public class ListView extends AbsListView {
}
if (needToMeasure) {
- int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec,
+ final int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec,
mListPadding.left + mListPadding.right, p.width);
- int lpHeight = p.height;
- int childHeightSpec;
+ final int lpHeight = p.height;
+ final int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 6631f26..6b8abab 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -292,14 +292,23 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// New state used to change background based on whether this TextView is multiline.
private static final int[] MULTILINE_STATE_SET = { R.attr.state_multiline };
- // System wide time for last cut, copy or text changed action.
- static long sLastCutCopyOrTextChangedTime;
+ // Accessibility action to share selected text.
+ private static final int ACCESSIBILITY_ACTION_SHARE = 0x10000000;
+
+ /**
+ * @hide
+ */
+ // Accessibility action start id for "process text" actions.
+ static final int ACCESSIBILITY_ACTION_PROCESS_TEXT_START_ID = 0x10000100;
/**
* @hide
*/
static final int PROCESS_TEXT_REQUEST_CODE = 100;
+ // System wide time for last cut, copy or text changed action.
+ static long sLastCutCopyOrTextChangedTime;
+
private ColorStateList mTextColor;
private ColorStateList mHintTextColor;
private ColorStateList mLinkTextColor;
@@ -5231,7 +5240,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// ExtractEditText does not call onFocus when it is displayed, and mHasSelectionOnFocus can
// not be set. Do the test here instead.
if (isInExtractedMode() && hasSelection() && mEditor != null
- && mEditor.mTextActionMode == null) {
+ && mEditor.mTextActionMode == null && isShown() && hasWindowFocus()) {
mEditor.startSelectionActionMode();
}
@@ -7574,10 +7583,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
String getSelectedText() {
- if (hasSelection()) {
- return String.valueOf(mText.subSequence(getSelectionStart(), getSelectionEnd()));
+ if (!hasSelection()) {
+ return null;
}
- return null;
+
+ final int start = getSelectionStart();
+ final int end = getSelectionEnd();
+ return String.valueOf(
+ start > end ? mText.subSequence(end, start) : mText.subSequence(start, end));
}
/**
@@ -8830,12 +8843,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
| AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
| AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
| AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+ info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION);
}
if (isFocused()) {
- if (canSelectText()) {
- info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION);
- }
if (canCopy()) {
info.addAction(AccessibilityNodeInfo.ACTION_COPY);
}
@@ -8845,6 +8856,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (canCut()) {
info.addAction(AccessibilityNodeInfo.ACTION_CUT);
}
+ if (canShare()) {
+ info.addAction(new AccessibilityNodeInfo.AccessibilityAction(
+ ACCESSIBILITY_ACTION_SHARE,
+ getResources().getString(com.android.internal.R.string.share)));
+ }
+ if (canProcessText()) { // also implies mEditor is not null.
+ mEditor.mProcessTextIntentActionsHandler.onInitializeAccessibilityNodeInfo(info);
+ }
}
// Check for known input filter types.
@@ -8869,6 +8888,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
@Override
public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
+ if (mEditor != null
+ && mEditor.mProcessTextIntentActionsHandler.performAccessibilityAction(action)) {
+ return true;
+ }
switch (action) {
case AccessibilityNodeInfo.ACTION_CLICK: {
boolean handled = false;
@@ -8919,30 +8942,28 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
} return false;
case AccessibilityNodeInfo.ACTION_SET_SELECTION: {
- if (isFocused() && canSelectText()) {
- ensureIterableTextForAccessibilitySelectable();
- CharSequence text = getIterableTextForAccessibility();
- if (text == null) {
- return false;
+ ensureIterableTextForAccessibilitySelectable();
+ CharSequence text = getIterableTextForAccessibility();
+ if (text == null) {
+ return false;
+ }
+ final int start = (arguments != null) ? arguments.getInt(
+ AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, -1) : -1;
+ final int end = (arguments != null) ? arguments.getInt(
+ AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, -1) : -1;
+ if ((getSelectionStart() != start || getSelectionEnd() != end)) {
+ // No arguments clears the selection.
+ if (start == end && end == -1) {
+ Selection.removeSelection((Spannable) text);
+ return true;
}
- final int start = (arguments != null) ? arguments.getInt(
- AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, -1) : -1;
- final int end = (arguments != null) ? arguments.getInt(
- AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, -1) : -1;
- if ((getSelectionStart() != start || getSelectionEnd() != end)) {
- // No arguments clears the selection.
- if (start == end && end == -1) {
- Selection.removeSelection((Spannable) text);
- return true;
- }
- if (start >= 0 && start <= end && end <= text.length()) {
- Selection.setSelection((Spannable) text, start, end);
- // Make sure selection mode is engaged.
- if (mEditor != null) {
- mEditor.startSelectionActionMode();
- }
- return true;
+ if (start >= 0 && start <= end && end <= text.length()) {
+ Selection.setSelection((Spannable) text, start, end);
+ // Make sure selection mode is engaged.
+ if (mEditor != null) {
+ mEditor.startSelectionActionMode();
}
+ return true;
}
}
} return false;
@@ -8951,6 +8972,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
ensureIterableTextForAccessibilitySelectable();
return super.performAccessibilityActionInternal(action, arguments);
}
+ case ACCESSIBILITY_ACTION_SHARE: {
+ if (isFocused() && canShare()) {
+ if (onTextContextMenuItem(ID_SHARE)) {
+ return true;
+ }
+ }
+ } return false;
default: {
return super.performAccessibilityActionInternal(action, arguments);
}
@@ -8960,6 +8988,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
/** @hide */
@Override
public void sendAccessibilityEventInternal(int eventType) {
+ if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED && mEditor != null) {
+ mEditor.mProcessTextIntentActionsHandler.initializeAccessibilityActions();
+ }
+
// Do not send scroll events since first they are not interesting for
// accessibility and second such events a generated too frequently.
// For details see the implementation of bringTextIntoView().
@@ -9658,6 +9690,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// controllers interact with how selection behaves.
if (mEditor != null) {
mEditor.hideCursorAndSpanControllers();
+ mEditor.stopTextActionMode();
}
CharSequence text = getIterableTextForAccessibility();
if (Math.min(start, end) >= 0 && Math.max(start, end) <= text.length()) {
diff --git a/core/java/com/android/internal/app/ExternalMediaFormatActivity.java b/core/java/com/android/internal/app/ExternalMediaFormatActivity.java
deleted file mode 100644
index fc213c5..0000000
--- a/core/java/com/android/internal/app/ExternalMediaFormatActivity.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2007 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.app;
-
-import com.android.internal.os.storage.ExternalStorageFormatter;
-
-import android.app.AlertDialog;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Bundle;
-import android.os.storage.StorageVolume;
-import android.util.Log;
-
-/**
- * This activity is shown to the user to confirm formatting of external media.
- * It uses the alert dialog style. It will be launched from a notification, or from settings
- */
-public class ExternalMediaFormatActivity extends AlertActivity implements DialogInterface.OnClickListener {
-
- private static final int POSITIVE_BUTTON = AlertDialog.BUTTON_POSITIVE;
-
- /** Used to detect when the media state changes, in case we need to call finish() */
- private BroadcastReceiver mStorageReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- Log.d("ExternalMediaFormatActivity", "got action " + action);
-
- if (action == Intent.ACTION_MEDIA_REMOVED ||
- action == Intent.ACTION_MEDIA_CHECKING ||
- action == Intent.ACTION_MEDIA_MOUNTED ||
- action == Intent.ACTION_MEDIA_SHARED) {
- finish();
- }
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- Log.d("ExternalMediaFormatActivity", "onCreate!");
- // Set up the "dialog"
- final AlertController.AlertParams p = mAlertParams;
- p.mTitle = getString(com.android.internal.R.string.extmedia_format_title);
- p.mMessage = getString(com.android.internal.R.string.extmedia_format_message);
- p.mPositiveButtonText = getString(com.android.internal.R.string.extmedia_format_button_format);
- p.mPositiveButtonListener = this;
- p.mNegativeButtonText = getString(com.android.internal.R.string.cancel);
- p.mNegativeButtonListener = this;
- setupAlert();
- }
-
- @Override
- protected void onResume() {
- super.onResume();
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_MEDIA_REMOVED);
- filter.addAction(Intent.ACTION_MEDIA_CHECKING);
- filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
- filter.addAction(Intent.ACTION_MEDIA_SHARED);
- registerReceiver(mStorageReceiver, filter);
- }
-
- @Override
- protected void onPause() {
- super.onPause();
-
- unregisterReceiver(mStorageReceiver);
- }
-
- /**
- * {@inheritDoc}
- */
- public void onClick(DialogInterface dialog, int which) {
-
- if (which == POSITIVE_BUTTON) {
- Intent intent = new Intent(ExternalStorageFormatter.FORMAT_ONLY);
- intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
- // Transfer the storage volume to the new intent
- final StorageVolume storageVolume = getIntent().getParcelableExtra(
- StorageVolume.EXTRA_STORAGE_VOLUME);
- intent.putExtra(StorageVolume.EXTRA_STORAGE_VOLUME, storageVolume);
- startService(intent);
- }
-
- // No matter what, finish the activity
- finish();
- }
-}
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 86c1b2f..201a124 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -25,6 +25,8 @@ interface IAppOpsService {
// be kept in sync with frameworks/native/include/binder/IAppOpsService.h
int checkOperation(int code, int uid, String packageName);
int noteOperation(int code, int uid, String packageName);
+ int noteProxyOperation(int code, String proxyPackageName,
+ int callingUid, String callingPackageName);
int startOperation(IBinder token, int code, int uid, String packageName);
void finishOperation(IBinder token, int code, int uid, String packageName);
void startWatchingMode(int op, String packageName, IAppOpsCallback callback);
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index a2bd700..8cd9bab 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -35,6 +35,7 @@ interface IVoiceInteractionManagerService {
boolean hideSessionFromSession(IBinder token);
int startVoiceActivity(IBinder token, in Intent intent, String resolvedType);
void setKeepAwake(IBinder token, boolean keepAwake);
+ void closeSystemDialogs(IBinder token);
void finish(IBinder token);
/**
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index f598828..233bee3 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -87,9 +87,9 @@ public class IntentForwarderActivity extends Activity {
if (canForward(newIntent, targetUserId)) {
if (newIntent.getAction().equals(Intent.ACTION_CHOOSER)) {
Intent innerIntent = (Intent) newIntent.getParcelableExtra(Intent.EXTRA_INTENT);
- innerIntent.setContentUserHint(callingUserId);
+ innerIntent.prepareToLeaveUser(callingUserId);
} else {
- newIntent.setContentUserHint(callingUserId);
+ newIntent.prepareToLeaveUser(callingUserId);
}
final android.content.pm.ResolveInfo ri = getPackageManager().resolveActivityAsUser(
diff --git a/core/java/com/android/internal/app/MediaRouteControllerDialog.java b/core/java/com/android/internal/app/MediaRouteControllerDialog.java
index b0e0373..4a468be 100644
--- a/core/java/com/android/internal/app/MediaRouteControllerDialog.java
+++ b/core/java/com/android/internal/app/MediaRouteControllerDialog.java
@@ -18,7 +18,7 @@ package com.android.internal.app;
import com.android.internal.R;
-import android.app.Dialog;
+import android.app.AlertDialog;
import android.app.MediaRouteActionProvider;
import android.app.MediaRouteButton;
import android.content.Context;
@@ -46,7 +46,7 @@ import android.widget.SeekBar;
*
* TODO: Move this back into the API, as in the support library media router.
*/
-public class MediaRouteControllerDialog extends Dialog {
+public class MediaRouteControllerDialog extends AlertDialog {
// Time to wait before updating the volume when the user lets go of the seek bar
// to allow the route provider time to propagate the change and publish a new
// route descriptor.
@@ -134,8 +134,6 @@ public class MediaRouteControllerDialog extends Dialog {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- getWindow().requestFeature(Window.FEATURE_LEFT_ICON);
-
setContentView(R.layout.media_route_controller_dialog);
mVolumeLayout = (LinearLayout)findViewById(R.id.media_route_volume_layout);
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index ac17cbe..742173b 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -1302,4 +1302,131 @@ public class InputMethodUtils {
return enabledInputMethodAndSubtypes;
}
}
+
+ // For spell checker service manager.
+ // TODO: Should we have TextServicesUtils.java?
+ private static final Locale LOCALE_EN_US = new Locale("en", "US");
+ private static final Locale LOCALE_EN_GB = new Locale("en", "GB");
+
+ /**
+ * Returns a list of {@link Locale} in the order of appropriateness for the default spell
+ * checker service.
+ *
+ * <p>If the system language is English, and the region is also explicitly specified in the
+ * system locale, the following fallback order will be applied.</p>
+ * <ul>
+ * <li>(system-locale-language, system-locale-region, system-locale-variant) (if exists)</li>
+ * <li>(system-locale-language, system-locale-region)</li>
+ * <li>("en", "US")</li>
+ * <li>("en", "GB")</li>
+ * <li>("en")</li>
+ * </ul>
+ *
+ * <p>If the system language is English, but no region is specified in the system locale,
+ * the following fallback order will be applied.</p>
+ * <ul>
+ * <li>("en")</li>
+ * <li>("en", "US")</li>
+ * <li>("en", "GB")</li>
+ * </ul>
+ *
+ * <p>If the system language is not English, the following fallback order will be applied.</p>
+ * <ul>
+ * <li>(system-locale-language, system-locale-region, system-locale-variant) (if exists)</li>
+ * <li>(system-locale-language, system-locale-region) (if exists)</li>
+ * <li>(system-locale-language) (if exists)</li>
+ * <li>("en", "US")</li>
+ * <li>("en", "GB")</li>
+ * <li>("en")</li>
+ * </ul>
+ *
+ * @param systemLocale the current system locale to be taken into consideration.
+ * @return a list of {@link Locale}. The first one is considered to be most appropriate.
+ */
+ @VisibleForTesting
+ public static ArrayList<Locale> getSuitableLocalesForSpellChecker(
+ @Nullable final Locale systemLocale) {
+ final Locale systemLocaleLanguageCountryVariant;
+ final Locale systemLocaleLanguageCountry;
+ final Locale systemLocaleLanguage;
+ if (systemLocale != null) {
+ final String language = systemLocale.getLanguage();
+ final boolean hasLanguage = !TextUtils.isEmpty(language);
+ final String country = systemLocale.getCountry();
+ final boolean hasCountry = !TextUtils.isEmpty(country);
+ final String variant = systemLocale.getVariant();
+ final boolean hasVariant = !TextUtils.isEmpty(variant);
+ if (hasLanguage && hasCountry && hasVariant) {
+ systemLocaleLanguageCountryVariant = new Locale(language, country, variant);
+ } else {
+ systemLocaleLanguageCountryVariant = null;
+ }
+ if (hasLanguage && hasCountry) {
+ systemLocaleLanguageCountry = new Locale(language, country);
+ } else {
+ systemLocaleLanguageCountry = null;
+ }
+ if (hasLanguage) {
+ systemLocaleLanguage = new Locale(language);
+ } else {
+ systemLocaleLanguage = null;
+ }
+ } else {
+ systemLocaleLanguageCountryVariant = null;
+ systemLocaleLanguageCountry = null;
+ systemLocaleLanguage = null;
+ }
+
+ final ArrayList<Locale> locales = new ArrayList<>();
+ if (systemLocaleLanguageCountryVariant != null) {
+ locales.add(systemLocaleLanguageCountryVariant);
+ }
+
+ if (Locale.ENGLISH.equals(systemLocaleLanguage)) {
+ if (systemLocaleLanguageCountry != null) {
+ // If the system language is English, and the region is also explicitly specified,
+ // following fallback order will be applied.
+ // - systemLocaleLanguageCountry [if systemLocaleLanguageCountry is non-null]
+ // - en_US [if systemLocaleLanguageCountry is non-null and not en_US]
+ // - en_GB [if systemLocaleLanguageCountry is non-null and not en_GB]
+ // - en
+ if (systemLocaleLanguageCountry != null) {
+ locales.add(systemLocaleLanguageCountry);
+ }
+ if (!LOCALE_EN_US.equals(systemLocaleLanguageCountry)) {
+ locales.add(LOCALE_EN_US);
+ }
+ if (!LOCALE_EN_GB.equals(systemLocaleLanguageCountry)) {
+ locales.add(LOCALE_EN_GB);
+ }
+ locales.add(Locale.ENGLISH);
+ } else {
+ // If the system language is English, but no region is specified, following
+ // fallback order will be applied.
+ // - en
+ // - en_US
+ // - en_GB
+ locales.add(Locale.ENGLISH);
+ locales.add(LOCALE_EN_US);
+ locales.add(LOCALE_EN_GB);
+ }
+ } else {
+ // If the system language is not English, the fallback order will be
+ // - systemLocaleLanguageCountry [if non-null]
+ // - systemLocaleLanguage [if non-null]
+ // - en_US
+ // - en_GB
+ // - en
+ if (systemLocaleLanguageCountry != null) {
+ locales.add(systemLocaleLanguageCountry);
+ }
+ if (systemLocaleLanguage != null) {
+ locales.add(systemLocaleLanguage);
+ }
+ locales.add(LOCALE_EN_US);
+ locales.add(LOCALE_EN_GB);
+ locales.add(Locale.ENGLISH);
+ }
+ return locales;
+ }
}
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index b78eca7..263e522 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -40,6 +40,10 @@ public class MetricsLogger implements MetricsConstants {
public static final int ACTION_BRIGHTNESS = 218;
public static final int ACTION_BRIGHTNESS_AUTO = 219;
public static final int BRIGHTNESS_DIALOG = 220;
+ public static final int SYSTEM_ALERT_WINDOW_APPS = 221;
+ public static final int DREAMING = 222;
+ public static final int DOZING = 223;
+
// Temporary constants go here, to await migration to MetricsConstants.
public static void visible(Context context, int category) throws IllegalArgumentException {
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index 6a85afb..264b8c1 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -480,6 +480,7 @@ public final class BatteryStatsHelper {
final boolean forAllUsers = (asUsers.get(UserHandle.USER_ALL) != null);
mStatsPeriod = mTypeBatteryRealtime;
+ BatterySipper osSipper = null;
final SparseArray<? extends Uid> uidStats = mStats.getUidStats();
final int NU = uidStats.size();
for (int iu = 0; iu < NU; iu++) {
@@ -526,15 +527,19 @@ public final class BatteryStatsHelper {
}
if (uid == 0) {
- // The device has probably been awake for longer than the screen on
- // time and application wake lock time would account for. Assign
- // this remainder to the OS, if possible.
- mWakelockPowerCalculator.calculateRemaining(app, mStats, mRawRealtime,
- mRawUptime, mStatsType);
- app.sumPower();
+ osSipper = app;
}
}
}
+
+ if (osSipper != null) {
+ // The device has probably been awake for longer than the screen on
+ // time and application wake lock time would account for. Assign
+ // this remainder to the OS, if possible.
+ mWakelockPowerCalculator.calculateRemaining(osSipper, mStats, mRawRealtime,
+ mRawUptime, mStatsType);
+ osSipper.sumPower();
+ }
}
private void addPhoneUsage() {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 1bd821d..8b4b994 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -106,7 +106,7 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 129 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 130 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -4386,6 +4386,7 @@ public final class BatteryStatsImpl extends BatteryStats {
LongSamplingCounter mUserCpuTime = new LongSamplingCounter(mOnBatteryTimeBase);
LongSamplingCounter mSystemCpuTime = new LongSamplingCounter(mOnBatteryTimeBase);
+ LongSamplingCounter mCpuPower = new LongSamplingCounter(mOnBatteryTimeBase);
LongSamplingCounter[] mSpeedBins;
/**
@@ -4978,6 +4979,11 @@ public final class BatteryStatsImpl extends BatteryStats {
}
@Override
+ public long getCpuPowerMaUs(int which) {
+ return mCpuPower.getCountLocked(which);
+ }
+
+ @Override
public long getTimeAtCpuSpeed(int step, int which) {
if (step >= 0 && step < mSpeedBins.length) {
if (mSpeedBins[step] != null) {
@@ -5097,6 +5103,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mUserCpuTime.reset(false);
mSystemCpuTime.reset(false);
+ mCpuPower.reset(false);
for (int i = 0; i < mSpeedBins.length; i++) {
LongSamplingCounter c = mSpeedBins[i];
if (c != null) {
@@ -5248,6 +5255,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mUserCpuTime.detach();
mSystemCpuTime.detach();
+ mCpuPower.detach();
for (int i = 0; i < mSpeedBins.length; i++) {
LongSamplingCounter c = mSpeedBins[i];
if (c != null) {
@@ -5427,6 +5435,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mUserCpuTime.writeToParcel(out);
mSystemCpuTime.writeToParcel(out);
+ mCpuPower.writeToParcel(out);
out.writeInt(mSpeedBins.length);
for (int i = 0; i < mSpeedBins.length; i++) {
@@ -5618,6 +5627,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mUserCpuTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
mSystemCpuTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
+ mCpuPower = new LongSamplingCounter(mOnBatteryTimeBase, in);
int bins = in.readInt();
int steps = getCpuSpeedSteps();
@@ -7964,7 +7974,8 @@ public final class BatteryStatsImpl extends BatteryStats {
mKernelUidCpuTimeReader.readDelta(!mOnBatteryInternal ? null :
new KernelUidCpuTimeReader.Callback() {
@Override
- public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs) {
+ public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs,
+ long powerMaUs) {
final Uid u = getUidStatsLocked(mapUid(uid));
// Accumulate the total system and user time.
@@ -7978,7 +7989,7 @@ public final class BatteryStatsImpl extends BatteryStats {
TimeUtils.formatDuration(userTimeUs / 1000, sb);
sb.append(" s=");
TimeUtils.formatDuration(systemTimeUs / 1000, sb);
- sb.append("\n");
+ sb.append(" p=").append(powerMaUs / 1000).append("mAms\n");
}
if (numWakelocksF > 0) {
@@ -7994,11 +8005,13 @@ public final class BatteryStatsImpl extends BatteryStats {
TimeUtils.formatDuration(userTimeUs / 1000, sb);
sb.append(" s=");
TimeUtils.formatDuration(systemTimeUs / 1000, sb);
+ sb.append(" p=").append(powerMaUs / 1000).append("mAms");
Slog.d(TAG, sb.toString());
}
u.mUserCpuTime.addCountLocked(userTimeUs);
u.mSystemCpuTime.addCountLocked(systemTimeUs);
+ u.mCpuPower.addCountLocked(powerMaUs);
// Add the cpu speeds to this UID. These are used as a ratio
// for computing the power this UID used.
@@ -9229,6 +9242,7 @@ public final class BatteryStatsImpl extends BatteryStats {
u.mUserCpuTime.readSummaryFromParcelLocked(in);
u.mSystemCpuTime.readSummaryFromParcelLocked(in);
+ u.mCpuPower.readSummaryFromParcelLocked(in);
int NSB = in.readInt();
if (NSB > 100) {
@@ -9575,6 +9589,7 @@ public final class BatteryStatsImpl extends BatteryStats {
u.mUserCpuTime.writeSummaryFromParcelLocked(out);
u.mSystemCpuTime.writeSummaryFromParcelLocked(out);
+ u.mCpuPower.writeSummaryFromParcelLocked(out);
out.writeInt(u.mSpeedBins.length);
for (int i = 0; i < u.mSpeedBins.length; i++) {
diff --git a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
index 41efd2c..45cc8b2 100644
--- a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
@@ -30,7 +30,7 @@ import java.io.IOException;
/**
* Reads /proc/uid_cputime/show_uid_stat which has the line format:
*
- * uid: user_time_micro_seconds system_time_micro_seconds
+ * uid: user_time_micro_seconds system_time_micro_seconds power_in_milli-amp-micro_seconds
*
* This provides the time a UID's processes spent executing in user-space and kernel-space.
* The file contains a monotonically increasing count of time for a single boot. This class
@@ -46,11 +46,18 @@ public class KernelUidCpuTimeReader {
* Callback interface for processing each line of the proc file.
*/
public interface Callback {
- void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs);
+ /**
+ * @param uid UID of the app
+ * @param userTimeUs time spent executing in user space in microseconds
+ * @param systemTimeUs time spent executing in kernel space in microseconds
+ * @param powerMaUs power consumed executing, in milli-ampere microseconds
+ */
+ void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs, long powerMaUs);
}
private SparseLongArray mLastUserTimeUs = new SparseLongArray();
private SparseLongArray mLastSystemTimeUs = new SparseLongArray();
+ private SparseLongArray mLastPowerMaUs = new SparseLongArray();
private long mLastTimeReadUs = 0;
/**
@@ -70,50 +77,65 @@ public class KernelUidCpuTimeReader {
final int uid = Integer.parseInt(uidStr.substring(0, uidStr.length() - 1), 10);
final long userTimeUs = Long.parseLong(splitter.next(), 10);
final long systemTimeUs = Long.parseLong(splitter.next(), 10);
+ final long powerMaUs;
+ if (splitter.hasNext()) {
+ powerMaUs = Long.parseLong(splitter.next(), 10) / 1000;
+ } else {
+ powerMaUs = 0;
+ }
if (callback != null) {
long userTimeDeltaUs = userTimeUs;
long systemTimeDeltaUs = systemTimeUs;
+ long powerDeltaMaUs = powerMaUs;
int index = mLastUserTimeUs.indexOfKey(uid);
if (index >= 0) {
userTimeDeltaUs -= mLastUserTimeUs.valueAt(index);
systemTimeDeltaUs -= mLastSystemTimeUs.valueAt(index);
+ powerDeltaMaUs -= mLastPowerMaUs.valueAt(index);
final long timeDiffUs = nowUs - mLastTimeReadUs;
- if (userTimeDeltaUs < 0 || systemTimeDeltaUs < 0 ||
+ if (userTimeDeltaUs < 0 || systemTimeDeltaUs < 0 || powerDeltaMaUs < 0 ||
userTimeDeltaUs > timeDiffUs || systemTimeDeltaUs > timeDiffUs) {
- StringBuilder sb = new StringBuilder("Malformed cpu data!\n");
+ StringBuilder sb = new StringBuilder("Malformed cpu data for UID=");
+ sb.append(uid).append("!\n");
sb.append("Time between reads: ");
TimeUtils.formatDuration(timeDiffUs / 1000, sb);
- sb.append("ms\n");
+ sb.append("\n");
sb.append("Previous times: u=");
TimeUtils.formatDuration(mLastUserTimeUs.valueAt(index) / 1000, sb);
- sb.append("ms s=");
+ sb.append(" s=");
TimeUtils.formatDuration(mLastSystemTimeUs.valueAt(index) / 1000, sb);
- sb.append("ms\n");
+ sb.append(" p=").append(mLastPowerMaUs.valueAt(index) / 1000);
+ sb.append("mAms\n");
+
sb.append("Current times: u=");
TimeUtils.formatDuration(userTimeUs / 1000, sb);
- sb.append("ms s=");
+ sb.append(" s=");
TimeUtils.formatDuration(systemTimeUs / 1000, sb);
- sb.append("ms\n");
- sb.append("Delta for UID=").append(uid).append(": u=");
+ sb.append(" p=").append(powerMaUs / 1000);
+ sb.append("mAms\n");
+ sb.append("Delta: u=");
TimeUtils.formatDuration(userTimeDeltaUs / 1000, sb);
- sb.append("ms s=");
+ sb.append(" s=");
TimeUtils.formatDuration(systemTimeDeltaUs / 1000, sb);
- sb.append("ms");
+ sb.append(" p=").append(powerDeltaMaUs / 1000).append("mAms");
Slog.wtf(TAG, sb.toString());
userTimeDeltaUs = 0;
systemTimeDeltaUs = 0;
+ powerDeltaMaUs = 0;
}
}
- if (userTimeDeltaUs != 0 || systemTimeDeltaUs != 0) {
- callback.onUidCpuTime(uid, userTimeDeltaUs, systemTimeDeltaUs);
+ if (userTimeDeltaUs != 0 || systemTimeDeltaUs != 0 || powerDeltaMaUs != 0) {
+ callback.onUidCpuTime(uid, userTimeDeltaUs, systemTimeDeltaUs,
+ powerDeltaMaUs);
}
}
mLastUserTimeUs.put(uid, userTimeUs);
mLastSystemTimeUs.put(uid, systemTimeUs);
+ mLastPowerMaUs.put(uid, powerMaUs);
}
} catch (IOException e) {
Slog.e(TAG, "Failed to read uid_cputime", e);
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index c97fdf4..197004c 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -46,8 +46,12 @@ public final class Zygote {
/** No external storage should be mounted. */
public static final int MOUNT_EXTERNAL_NONE = 0;
- /** Default user-specific external storage should be mounted. */
+ /** Default external storage should be mounted. */
public static final int MOUNT_EXTERNAL_DEFAULT = 1;
+ /** Read-only external storage should be mounted. */
+ public static final int MOUNT_EXTERNAL_READ = 2;
+ /** Read-write external storage should be mounted. */
+ public static final int MOUNT_EXTERNAL_WRITE = 3;
private static final ZygoteHooks VM_HOOKS = new ZygoteHooks();
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index fa870b9..3e86fac 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -519,6 +519,10 @@ class ZygoteConnection {
niceName = arg.substring(arg.indexOf('=') + 1);
} else if (arg.equals("--mount-external-default")) {
mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
+ } else if (arg.equals("--mount-external-read")) {
+ mountExternal = Zygote.MOUNT_EXTERNAL_READ;
+ } else if (arg.equals("--mount-external-write")) {
+ mountExternal = Zygote.MOUNT_EXTERNAL_WRITE;
} else if (arg.equals("--query-abi-list")) {
abiListQuery = true;
} else if (arg.startsWith("--instruction-set=")) {
diff --git a/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java b/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
index 1d0511f..0a01ae9 100644
--- a/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
+++ b/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
@@ -17,6 +17,10 @@ import com.android.internal.R;
/**
* Takes care of unmounting and formatting external storage.
+ *
+ * @deprecated Please use {@link Intent#ACTION_MASTER_CLEAR} broadcast with extra
+ * {@link Intent#EXTRA_WIPE_EXTERNAL_STORAGE} to wipe and factory reset, or call
+ * {@link StorageManager#wipeAdoptableDisks} directly to format external storages.
*/
public class ExternalStorageFormatter extends Service {
static final String TAG = "ExternalStorageFormatter";
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index aea1585..63bfbe5 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -44,7 +44,7 @@ interface IStatusBarService
// You need the STATUS_BAR_SERVICE permission
void registerStatusBar(IStatusBar callbacks, out StatusBarIconList iconList,
out int[] switches, out List<IBinder> binders);
- void onPanelRevealed(boolean clearNotificationEffects);
+ void onPanelRevealed(boolean clearNotificationEffects, int numItems);
void onPanelHidden();
// Mark current notifications as "seen" and stop ringing, vibrating, blinking.
void clearNotificationEffects();
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index 863506b..b2699f8 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -30,6 +30,8 @@ import com.android.internal.util.Preconditions;
import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.widget.FloatingToolbar;
+import java.util.Arrays;
+
public class FloatingActionMode extends ActionMode {
private static final int MAX_HIDE_DURATION = 3000;
@@ -42,7 +44,9 @@ public class FloatingActionMode extends ActionMode {
private final Rect mContentRectOnWindow;
private final Rect mPreviousContentRectOnWindow;
private final int[] mViewPosition;
+ private final int[] mPreviousViewPosition;
private final Rect mViewRect;
+ private final Rect mPreviousViewRect;
private final Rect mScreenRect;
private final View mOriginatingView;
private final int mBottomAllowance;
@@ -75,7 +79,9 @@ public class FloatingActionMode extends ActionMode {
mContentRectOnWindow = new Rect();
mPreviousContentRectOnWindow = new Rect();
mViewPosition = new int[2];
+ mPreviousViewPosition = new int[2];
mViewRect = new Rect();
+ mPreviousViewRect = new Rect();
mScreenRect = new Rect();
mOriginatingView = Preconditions.checkNotNull(originatingView);
mOriginatingView.getLocationInWindow(mViewPosition);
@@ -129,9 +135,17 @@ public class FloatingActionMode extends ActionMode {
public void updateViewLocationInWindow() {
checkToolbarInitialized();
+
mOriginatingView.getLocationInWindow(mViewPosition);
mOriginatingView.getGlobalVisibleRect(mViewRect);
- repositionToolbar();
+
+ if (!Arrays.equals(mViewPosition, mPreviousViewPosition)
+ || !mViewRect.equals(mPreviousViewRect)) {
+ repositionToolbar();
+ mPreviousViewPosition[0] = mViewPosition[0];
+ mPreviousViewPosition[1] = mViewPosition[1];
+ mPreviousViewRect.set(mViewRect);
+ }
}
private void repositionToolbar() {
@@ -153,6 +167,7 @@ public class FloatingActionMode extends ActionMode {
// Content rect is moving.
mOriginatingView.removeCallbacks(mMovingOff);
mFloatingToolbarVisibilityHelper.setMoving(true);
+ mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY);
mFloatingToolbar.setContentRect(mContentRectOnWindow);
@@ -160,9 +175,9 @@ public class FloatingActionMode extends ActionMode {
}
} else {
mFloatingToolbarVisibilityHelper.setOutOfBounds(true);
+ mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
mContentRectOnWindow.setEmpty();
}
- mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
mPreviousContentRectOnWindow.set(mContentRectOnWindow);
}
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index 3b1f20d..08d4e86 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -593,7 +593,7 @@ public final class MenuItemImpl implements MenuItem {
public MenuItem setActionProvider(ActionProvider actionProvider) {
if (mActionProvider != null) {
- mActionProvider.setVisibilityListener(null);
+ mActionProvider.reset();
}
mActionView = null;
mActionProvider = actionProvider;
diff --git a/core/java/com/android/internal/widget/DrawingSpace.java b/core/java/com/android/internal/widget/DrawingSpace.java
new file mode 100644
index 0000000..b8222db
--- /dev/null
+++ b/core/java/com/android/internal/widget/DrawingSpace.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+
+/**
+ * Implementation of {@link android.widget.Space} that uses normal View drawing
+ * rather than a no-op. Useful for dialogs and other places where the base View
+ * class is too greedy when measured with AT_MOST.
+ */
+public final class DrawingSpace extends View {
+ public DrawingSpace(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public DrawingSpace(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public DrawingSpace(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public DrawingSpace(Context context) {
+ this(context, null);
+ }
+
+ /**
+ * Compare to: {@link View#getDefaultSize(int, int)}
+ * <p>
+ * If mode is AT_MOST, return the child size instead of the parent size
+ * (unless it is too big).
+ */
+ private static int getDefaultSizeNonGreedy(int size, int measureSpec) {
+ int result = size;
+ int specMode = MeasureSpec.getMode(measureSpec);
+ int specSize = MeasureSpec.getSize(measureSpec);
+
+ switch (specMode) {
+ case MeasureSpec.UNSPECIFIED:
+ result = size;
+ break;
+ case MeasureSpec.AT_MOST:
+ result = Math.min(size, specSize);
+ break;
+ case MeasureSpec.EXACTLY:
+ result = specSize;
+ break;
+ }
+ return result;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ setMeasuredDimension(
+ getDefaultSizeNonGreedy(getSuggestedMinimumWidth(), widthMeasureSpec),
+ getDefaultSizeNonGreedy(getSuggestedMinimumHeight(), heightMeasureSpec));
+ }
+}
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 523663c..a6e8034 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -23,6 +23,7 @@ import android.animation.ObjectAnimator;
import android.content.ComponentCallbacks;
import android.content.Context;
import android.content.res.Configuration;
+import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
@@ -30,6 +31,7 @@ import android.graphics.Region;
import android.graphics.drawable.ColorDrawable;
import android.text.TextUtils;
import android.util.Size;
+import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -83,6 +85,7 @@ public final class FloatingToolbar {
private final FloatingToolbarPopup mPopup;
private final Rect mContentRect = new Rect();
+ private final Rect mPreviousContentRect = new Rect();
private Menu mMenu;
private List<Object> mShowingMenuItems = new ArrayList<Object>();
@@ -108,8 +111,10 @@ public final class FloatingToolbar {
* Initializes a floating toolbar.
*/
public FloatingToolbar(Context context, Window window) {
- mContext = Preconditions.checkNotNull(context);
- mPopup = new FloatingToolbarPopup(window.getDecorView());
+ Preconditions.checkNotNull(context);
+ Preconditions.checkNotNull(window);
+ mContext = applyDefaultTheme(context);
+ mPopup = new FloatingToolbarPopup(mContext, window.getDecorView());
}
/**
@@ -174,11 +179,13 @@ public final class FloatingToolbar {
mPopup.layoutMenuItems(menuItems, mMenuItemClickListener, mSuggestedWidth);
mShowingMenuItems = getShowingMenuItemsReferences(menuItems);
}
- mPopup.updateCoordinates(mContentRect);
if (!mPopup.isShowing()) {
mPopup.show(mContentRect);
+ } else if (!mPreviousContentRect.equals(mContentRect)) {
+ mPopup.updateCoordinates(mContentRect);
}
mWidthChanged = false;
+ mPreviousContentRect.set(mContentRect);
return this;
}
@@ -276,6 +283,7 @@ public final class FloatingToolbar {
public static final int OVERFLOW_DIRECTION_UP = 0;
public static final int OVERFLOW_DIRECTION_DOWN = 1;
+ private final Context mContext;
private final View mParent;
private final PopupWindow mPopupWindow;
private final ViewGroup mContentContainer;
@@ -313,24 +321,8 @@ public final class FloatingToolbar {
};
private final AnimatorSet mDismissAnimation;
private final AnimatorSet mHideAnimation;
- private final AnimationSet mOpenOverflowAnimation = new AnimationSet(true) {
- @Override
- public void cancel() {
- if (hasStarted() && !hasEnded()) {
- super.cancel();
- setOverflowPanelAsContent();
- }
- }
- };
- private final AnimationSet mCloseOverflowAnimation = new AnimationSet(true) {
- @Override
- public void cancel() {
- if (hasStarted() && !hasEnded()) {
- super.cancel();
- setMainPanelAsContent();
- }
- }
- };
+ private final AnimationSet mOpenOverflowAnimation = new AnimationSet(true);
+ private final AnimationSet mCloseOverflowAnimation = new AnimationSet(true);
private final Runnable mOpenOverflow = new Runnable() {
@Override
@@ -375,9 +367,10 @@ public final class FloatingToolbar {
* @param parent A parent view to get the {@link android.view.View#getWindowToken()} token
* from.
*/
- public FloatingToolbarPopup(View parent) {
+ public FloatingToolbarPopup(Context context, View parent) {
mParent = Preconditions.checkNotNull(parent);
- mContentContainer = createContentContainer(parent.getContext());
+ mContext = Preconditions.checkNotNull(context);
+ mContentContainer = createContentContainer(context);
mPopupWindow = createPopupWindow(mContentContainer);
mDismissAnimation = createExitAnimation(
mContentContainer,
@@ -415,7 +408,7 @@ public final class FloatingToolbar {
mContentContainer.removeAllViews();
if (mMainPanel == null) {
- mMainPanel = new FloatingToolbarMainPanel(mParent.getContext(), mOpenOverflow);
+ mMainPanel = new FloatingToolbarMainPanel(mContext, mOpenOverflow);
}
List<MenuItem> overflowMenuItems =
mMainPanel.layoutMenuItems(menuItems, getToolbarWidth(suggestedWidth));
@@ -423,7 +416,7 @@ public final class FloatingToolbar {
if (!overflowMenuItems.isEmpty()) {
if (mOverflowPanel == null) {
mOverflowPanel =
- new FloatingToolbarOverflowPanel(mParent.getContext(), mCloseOverflow);
+ new FloatingToolbarOverflowPanel(mContext, mCloseOverflow);
}
mOverflowPanel.setMenuItems(overflowMenuItems);
mOverflowPanel.setOnMenuItemClickListener(menuItemClickListener);
@@ -540,7 +533,7 @@ public final class FloatingToolbar {
* Returns the context this popup is running in.
*/
public Context getContext() {
- return mContentContainer.getContext();
+ return mContext;
}
private void refreshCoordinatesAndOverflowDirection(Rect contentRect) {
@@ -562,7 +555,7 @@ public final class FloatingToolbar {
} else if (availableHeightBelowContent >= getToolbarHeightWithVerticalMargin()) {
// There is enough space at the bottom of the content.
y = contentRect.bottom;
- } else if (availableHeightBelowContent >= getEstimatedToolbarHeight(getContext())) {
+ } else if (availableHeightBelowContent >= getEstimatedToolbarHeight(mContext)) {
// Just enough space to fit the toolbar with no vertical margins.
y = contentRect.bottom - mMarginVertical;
} else {
@@ -621,7 +614,7 @@ public final class FloatingToolbar {
}
private int getToolbarHeightWithVerticalMargin() {
- return getEstimatedToolbarHeight(mParent.getContext()) + mMarginVertical * 2;
+ return getEstimatedToolbarHeight(mContext) + mMarginVertical * 2;
}
/**
@@ -651,8 +644,24 @@ public final class FloatingToolbar {
}
private void cancelOverflowAnimations() {
- mOpenOverflowAnimation.cancel();
- mCloseOverflowAnimation.cancel();
+ if (mOpenOverflowAnimation.hasStarted()
+ && !mOpenOverflowAnimation.hasEnded()) {
+ // Remove the animation listener, stop the animation,
+ // then trigger the lister explicitly so it is not posted
+ // to the message queue.
+ mOpenOverflowAnimation.setAnimationListener(null);
+ mContentContainer.clearAnimation();
+ mOnOverflowOpened.onAnimationEnd(null);
+ }
+ if (mCloseOverflowAnimation.hasStarted()
+ && !mCloseOverflowAnimation.hasEnded()) {
+ // Remove the animation listener, stop the animation,
+ // then trigger the lister explicitly so it is not posted
+ // to the message queue.
+ mCloseOverflowAnimation.setAnimationListener(null);
+ mContentContainer.clearAnimation();
+ mOnOverflowClosed.onAnimationEnd(null);
+ }
}
/**
@@ -1126,7 +1135,7 @@ public final class FloatingToolbar {
private final Runnable mCloseOverflow;
private MenuItem.OnMenuItemClickListener mOnMenuItemClickListener;
- private int mOverflowWidth = 0;
+ private int mOverflowWidth;
private int mSuggestedHeight;
/**
@@ -1137,7 +1146,6 @@ public final class FloatingToolbar {
*/
public FloatingToolbarOverflowPanel(Context context, Runnable closeOverflow) {
mCloseOverflow = Preconditions.checkNotNull(closeOverflow);
- mSuggestedHeight = getScreenHeight(context);
mContentView = new LinearLayout(context);
mContentView.setOrientation(LinearLayout.VERTICAL);
@@ -1261,7 +1269,8 @@ public final class FloatingToolbar {
mListView.setLayoutParams(params);
}
- private int setOverflowWidth() {
+ private void setOverflowWidth() {
+ mOverflowWidth = 0;
for (int i = 0; i < mListView.getAdapter().getCount(); i++) {
MenuItem menuItem = (MenuItem) mListView.getAdapter().getItem(i);
Preconditions.checkNotNull(menuItem);
@@ -1271,7 +1280,6 @@ public final class FloatingToolbar {
mOverflowWidth = Math.max(
mListViewItemWidthCalculator.getMeasuredWidth(), mOverflowWidth);
}
- return mOverflowWidth;
}
private ListView createOverflowListView() {
@@ -1477,6 +1485,17 @@ public final class FloatingToolbar {
return animation;
}
+ /**
+ * Returns a re-themed context with controlled look and feel for views.
+ */
+ private static Context applyDefaultTheme(Context originalContext) {
+ TypedArray a = originalContext.obtainStyledAttributes(new int[]{R.attr.isLightTheme});
+ boolean isLightTheme = a.getBoolean(0, true);
+ int themeId = isLightTheme ? R.style.Theme_Material_Light : R.style.Theme_Material;
+ a.recycle();
+ return new ContextThemeWrapper(originalContext, themeId);
+ }
+
private static int getEstimatedToolbarHeight(Context context) {
return context.getResources().getDimensionPixelSize(R.dimen.floating_toolbar_height);
}
@@ -1485,30 +1504,4 @@ public final class FloatingToolbar {
return context.getResources()
.getDimensionPixelSize(R.dimen.floating_toolbar_menu_button_minimum_width);
}
-
- private static int getAdjustedToolbarWidth(Context context, int width) {
- int maximumWidth = getScreenWidth(context) - 2 * context.getResources()
- .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin);
-
- if (width <= 0 || width > maximumWidth) {
- int defaultWidth = context.getResources()
- .getDimensionPixelSize(R.dimen.floating_toolbar_preferred_width);
- width = Math.min(defaultWidth, maximumWidth);
- }
- return width;
- }
-
- /**
- * Returns the device's screen width.
- */
- private static int getScreenWidth(Context context) {
- return context.getResources().getDisplayMetrics().widthPixels;
- }
-
- /**
- * Returns the device's screen height.
- */
- private static int getScreenHeight(Context context) {
- return context.getResources().getDisplayMetrics().heightPixels;
- }
}
diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java
index e76302b..a2c4f6a 100644
--- a/core/java/com/android/internal/widget/ViewPager.java
+++ b/core/java/com/android/internal/widget/ViewPager.java
@@ -85,7 +85,7 @@ import java.util.Comparator;
*/
public class ViewPager extends ViewGroup {
private static final String TAG = "ViewPager";
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
private static final int MAX_SCROLL_X = 2 << 23;
private static final boolean USE_CACHE = false;
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index c9d609c..1356c99 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -130,7 +130,6 @@ getInternedString(JNIEnv *env, const String8* string) {
internedStrings.insert(std::make_pair(string, internedString));
env->DeleteLocalRef(localString);
}
-
return internedString;
}
@@ -182,10 +181,9 @@ nativeGetNextSensor(JNIEnv *env, jclass clazz, jlong sensorManager, jobject sens
return size_t(next) < count ? next : 0;
}
-static int nativeEnableDataInjection(JNIEnv *_env, jclass _this, jlong sensorManager,
- jboolean enable) {
+static jboolean nativeIsDataInjectionEnabled(JNIEnv *_env, jclass _this, jlong sensorManager) {
SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
- return mgr->enableDataInjection(enable);
+ return mgr->isDataInjectionEnabled();
}
//----------------------------------------------------------------------------
@@ -358,9 +356,9 @@ static JNINativeMethod gSystemSensorManagerMethods[] = {
"(JLandroid/hardware/Sensor;I)I",
(void*)nativeGetNextSensor },
- {"nativeEnableDataInjection",
- "(JZ)I",
- (void*)nativeEnableDataInjection },
+ {"nativeIsDataInjectionEnabled",
+ "(J)Z",
+ (void*)nativeIsDataInjectionEnabled},
};
static JNINativeMethod gBaseEventQueueMethods[] = {
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 70a7805..c139cd7 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -682,18 +682,30 @@ void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
break;
case FAILED_TRANSACTION: {
ALOGE("!!! FAILED BINDER TRANSACTION !!! (parcel size = %d)", parcelSize);
+ const char* exceptionToThrow;
char msg[128];
- snprintf(msg, sizeof(msg)-1, "data parcel size %d bytes", parcelSize);
// TransactionTooLargeException is a checked exception, only throw from certain methods.
// FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION
// but it is not the only one. The Binder driver can return BR_FAILED_REPLY
// for other reasons also, such as if the transaction is malformed or
// refers to an FD that has been closed. We should change the driver
// to enable us to distinguish these cases in the future.
- jniThrowException(env, canThrowRemoteException
- ? "android/os/TransactionTooLargeException"
- : "java/lang/RuntimeException",
- parcelSize > 0 ? msg : NULL);
+ if (canThrowRemoteException && parcelSize > 200*1024) {
+ // bona fide large payload
+ exceptionToThrow = "android/os/TransactionTooLargeException";
+ snprintf(msg, sizeof(msg)-1, "data parcel size %d bytes", parcelSize);
+ } else {
+ // Heuristic: a payload smaller than this threshold "shouldn't" be too
+ // big, so it's probably some other, more subtle problem. In practice
+ // it seems to always mean that the remote process died while the binder
+ // transaction was already in flight.
+ exceptionToThrow = (canThrowRemoteException)
+ ? "android/os/DeadObjectException"
+ : "java/lang/RuntimeException";
+ snprintf(msg, sizeof(msg)-1,
+ "Transaction failed on small parcel; remote process probably died");
+ }
+ jniThrowException(env, exceptionToThrow, msg);
} break;
case FDS_NOT_ALLOWED:
jniThrowException(env, "java/lang/RuntimeException",
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 76db5d3..db88962 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -20,9 +20,13 @@
#include <sys/mount.h>
#include <linux/fs.h>
+#include <list>
+#include <string>
+
#include <fcntl.h>
#include <grp.h>
#include <inttypes.h>
+#include <mntent.h>
#include <paths.h>
#include <signal.h>
#include <stdlib.h>
@@ -66,6 +70,8 @@ static jmethodID gCallPostForkChildHooks;
enum MountExternalKind {
MOUNT_EXTERNAL_NONE = 0,
MOUNT_EXTERNAL_DEFAULT = 1,
+ MOUNT_EXTERNAL_READ = 2,
+ MOUNT_EXTERNAL_WRITE = 3,
};
static void RuntimeAbort(JNIEnv* env) {
@@ -247,40 +253,79 @@ static void SetSchedulerPolicy(JNIEnv* env) {
}
}
-// Create a private mount namespace and bind mount appropriate emulated
-// storage for the given user.
-static bool MountEmulatedStorage(uid_t uid, jint mount_mode, bool force_mount_namespace) {
- if (mount_mode == MOUNT_EXTERNAL_NONE && !force_mount_namespace) {
- return true;
- }
+static int UnmountTree(const char* path) {
+ size_t path_len = strlen(path);
- // Create a second private mount namespace for our process
- if (unshare(CLONE_NEWNS) == -1) {
- ALOGW("Failed to unshare(): %s", strerror(errno));
- return false;
- }
+ FILE* fp = setmntent("/proc/mounts", "r");
+ if (fp == NULL) {
+ ALOGE("Error opening /proc/mounts: %s", strerror(errno));
+ return -errno;
+ }
- if (mount_mode == MOUNT_EXTERNAL_NONE) {
- return true;
- }
+ // Some volumes can be stacked on each other, so force unmount in
+ // reverse order to give us the best chance of success.
+ std::list<std::string> toUnmount;
+ mntent* mentry;
+ while ((mentry = getmntent(fp)) != NULL) {
+ if (strncmp(mentry->mnt_dir, path, path_len) == 0) {
+ toUnmount.push_front(std::string(mentry->mnt_dir));
+ }
+ }
+ endmntent(fp);
- // See storage config details at http://source.android.com/tech/storage/
- userid_t user_id = multiuser_get_user_id(uid);
+ for (auto path : toUnmount) {
+ if (umount2(path.c_str(), MNT_DETACH)) {
+ ALOGW("Failed to unmount %s: %s", path.c_str(), strerror(errno));
+ }
+ }
+ return 0;
+}
- // Bind mount user-specific storage into place
- const String8 source(String8::format("/mnt/user/%d", user_id));
- const String8 target(String8::format("/storage/self"));
+// Create a private mount namespace and bind mount appropriate emulated
+// storage for the given user.
+static bool MountEmulatedStorage(uid_t uid, jint mount_mode,
+ bool force_mount_namespace) {
+ // See storage config details at http://source.android.com/tech/storage/
- if (fs_prepare_dir(source.string(), 0755, 0, 0) == -1) {
- return false;
- }
+ // Create a second private mount namespace for our process
+ if (unshare(CLONE_NEWNS) == -1) {
+ ALOGW("Failed to unshare(): %s", strerror(errno));
+ return false;
+ }
- if (TEMP_FAILURE_RETRY(mount(source.string(), target.string(), NULL, MS_BIND, NULL)) == -1) {
- ALOGW("Failed to mount %s to %s: %s", source.string(), target.string(), strerror(errno));
- return false;
- }
+ // Unmount storage provided by root namespace and mount requested view
+ UnmountTree("/storage");
+
+ String8 storageSource;
+ if (mount_mode == MOUNT_EXTERNAL_DEFAULT) {
+ storageSource = "/mnt/runtime_default";
+ } else if (mount_mode == MOUNT_EXTERNAL_READ) {
+ storageSource = "/mnt/runtime_read";
+ } else if (mount_mode == MOUNT_EXTERNAL_WRITE) {
+ storageSource = "/mnt/runtime_write";
+ } else {
+ // Sane default of no storage visible
+ return true;
+ }
+ if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage",
+ NULL, MS_BIND | MS_REC | MS_SLAVE, NULL)) == -1) {
+ ALOGW("Failed to mount %s to /storage: %s", storageSource.string(), strerror(errno));
+ return false;
+ }
- return true;
+ // Mount user-specific symlink helper into place
+ userid_t user_id = multiuser_get_user_id(uid);
+ const String8 userSource(String8::format("/mnt/user/%d", user_id));
+ if (fs_prepare_dir(userSource.string(), 0751, 0, 0) == -1) {
+ return false;
+ }
+ if (TEMP_FAILURE_RETRY(mount(userSource.string(), "/storage/self",
+ NULL, MS_BIND, NULL)) == -1) {
+ ALOGW("Failed to mount %s to /storage/self: %s", userSource.string(), strerror(errno));
+ return false;
+ }
+
+ return true;
}
static bool NeedsNoRandomizeWorkaround() {
@@ -543,7 +588,7 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer(
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
debug_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
- MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL,
+ MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
NULL, NULL);
if (pid > 0) {
// The zygote process checks whether the child process has died or not.
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9637cf5..4c1626a 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -335,14 +335,18 @@
android:description="@string/permgroupdesc_contacts"
android:priority="100" />
- <!-- Allows an application to read the user's contacts data. -->
+ <!-- Allows an application to read the user's contacts data.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.READ_CONTACTS"
android:permissionGroup="android.permission-group.CONTACTS"
android:label="@string/permlab_readContacts"
android:description="@string/permdesc_readContacts"
android:protectionLevel="dangerous" />
- <!-- Allows an application to write the user's contacts data. -->
+ <!-- Allows an application to write the user's contacts data.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.WRITE_CONTACTS"
android:permissionGroup="android.permission-group.CONTACTS"
android:label="@string/permlab_writeContacts"
@@ -361,14 +365,18 @@
android:description="@string/permgroupdesc_calendar"
android:priority="200" />
- <!-- Allows an application to read the user's calendar data. -->
+ <!-- Allows an application to read the user's calendar data.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.READ_CALENDAR"
android:permissionGroup="android.permission-group.CALENDAR"
android:label="@string/permlab_readCalendar"
android:description="@string/permdesc_readCalendar"
android:protectionLevel="dangerous" />
- <!-- Allows an application to write the user's calendar data. -->
+ <!-- Allows an application to write the user's calendar data.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.WRITE_CALENDAR"
android:permissionGroup="android.permission-group.CALENDAR"
android:label="@string/permlab_writeCalendar"
@@ -387,7 +395,9 @@
android:description="@string/permgroupdesc_sms"
android:priority="300" />
- <!-- Allows an application to send SMS messages. -->
+ <!-- Allows an application to send SMS messages.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.SEND_SMS"
android:permissionGroup="android.permission-group.SMS"
android:label="@string/permlab_sendSms"
@@ -395,28 +405,36 @@
android:permissionFlags="costsMoney"
android:protectionLevel="dangerous" />
- <!-- Allows an application to receive SMS messages. -->
+ <!-- Allows an application to receive SMS messages.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.RECEIVE_SMS"
android:permissionGroup="android.permission-group.SMS"
android:label="@string/permlab_receiveSms"
android:description="@string/permdesc_receiveSms"
android:protectionLevel="dangerous"/>
- <!-- Allows an application to read SMS messages. -->
+ <!-- Allows an application to read SMS messages.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.READ_SMS"
android:permissionGroup="android.permission-group.SMS"
android:label="@string/permlab_readSms"
android:description="@string/permdesc_readSms"
android:protectionLevel="dangerous" />
- <!-- Allows an application to receive WAP push messages. -->
+ <!-- Allows an application to receive WAP push messages.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.RECEIVE_WAP_PUSH"
android:permissionGroup="android.permission-group.SMS"
android:label="@string/permlab_receiveWapPush"
android:description="@string/permdesc_receiveWapPush"
android:protectionLevel="dangerous" />
- <!-- Allows an application to monitor incoming MMS messages. -->
+ <!-- Allows an application to monitor incoming MMS messages.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.RECEIVE_MMS"
android:permissionGroup="android.permission-group.SMS"
android:label="@string/permlab_receiveMms"
@@ -433,6 +451,7 @@
additional emergency information (if Internet access is available)
when the alert is first received, and to delay presenting the info
to the user until after the initial alert dialog is dismissed.
+ <p>Protection level: dangerous
@hide Pending API council approval -->
<permission android:name="android.permission.READ_CELL_BROADCASTS"
android:permissionGroup="android.permission-group.SMS"
@@ -471,7 +490,9 @@
targetSdkVersion}</a> values are set to 3 or lower, the system implicitly
grants your app this permission. If you don't need this permission, be sure your <a
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
- targetSdkVersion}</a> is 4 or higher.-->
+ targetSdkVersion}</a> is 4 or higher.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:permissionGroup="android.permission-group.STORAGE"
android:label="@string/permlab_sdcardRead"
@@ -490,7 +511,9 @@
<p>Starting in API level 19, this permission is <em>not</em> required to
read/write files in your application-specific directories returned by
{@link android.content.Context#getExternalFilesDir} and
- {@link android.content.Context#getExternalCacheDir}. -->
+ {@link android.content.Context#getExternalCacheDir}.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:permissionGroup="android.permission-group.STORAGE"
android:label="@string/permlab_sdcardWrite"
@@ -509,14 +532,18 @@
android:description="@string/permgroupdesc_location"
android:priority="400" />
- <!-- Allows an app to access precise location. -->
+ <!-- Allows an app to access precise location.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.ACCESS_FINE_LOCATION"
android:permissionGroup="android.permission-group.LOCATION"
android:label="@string/permlab_accessFineLocation"
android:description="@string/permdesc_accessFineLocation"
android:protectionLevel="dangerous" />
- <!-- Allows an app to access approximate location. -->
+ <!-- Allows an app to access approximate location.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.ACCESS_COARSE_LOCATION"
android:permissionGroup="android.permission-group.LOCATION"
android:label="@string/permlab_accessCoarseLocation"
@@ -543,7 +570,9 @@
targetSdkVersion}</a> values are set to 3 or lower, the system implicitly
grants your app this permission. If you don't need this permission, be sure your <a
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
- targetSdkVersion}</a> is 4 or higher. -->
+ targetSdkVersion}</a> is 4 or higher.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.READ_PHONE_STATE"
android:permissionGroup="android.permission-group.PHONE"
android:label="@string/permlab_readPhoneState"
@@ -551,7 +580,9 @@
android:protectionLevel="dangerous" />
<!-- Allows an application to initiate a phone call without going through
- the Dialer user interface for the user to confirm the call. -->
+ the Dialer user interface for the user to confirm the call.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.CALL_PHONE"
android:permissionGroup="android.permission-group.PHONE"
android:permissionFlags="costsMoney"
@@ -568,7 +599,9 @@
targetSdkVersion}</a> values are set to 15 or lower, the system implicitly
grants your app this permission. If you don't need this permission, be sure your <a
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
- targetSdkVersion}</a> is 16 or higher.</p> -->
+ targetSdkVersion}</a> is 16 or higher.</p>
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.READ_CALL_LOG"
android:permissionGroup="android.permission-group.PHONE"
android:label="@string/permlab_readCallLog"
@@ -585,21 +618,27 @@
targetSdkVersion}</a> values are set to 15 or lower, the system implicitly
grants your app this permission. If you don't need this permission, be sure your <a
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
- targetSdkVersion}</a> is 16 or higher.</p> -->
+ targetSdkVersion}</a> is 16 or higher.</p>
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.WRITE_CALL_LOG"
android:permissionGroup="android.permission-group.PHONE"
android:label="@string/permlab_writeCallLog"
android:description="@string/permdesc_writeCallLog"
android:protectionLevel="dangerous" />
- <!-- Allows an application to add voicemails into the system. -->
+ <!-- Allows an application to add voicemails into the system.
+ <p>Protection level: dangerous
+ -->
<permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL"
android:permissionGroup="android.permission-group.PHONE"
android:label="@string/permlab_addVoicemail"
android:description="@string/permdesc_addVoicemail"
android:protectionLevel="dangerous" />
- <!-- Allows an application to use SIP service. -->
+ <!-- Allows an application to use SIP service.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.USE_SIP"
android:permissionGroup="android.permission-group.PHONE"
android:description="@string/permdesc_use_sip"
@@ -608,7 +647,9 @@
<!-- Allows an application to see the number being dialed during an outgoing
call with the option to redirect the call to a different number or
- abort the call altogether. -->
+ abort the call altogether.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
android:permissionGroup="android.permission-group.PHONE"
android:label="@string/permlab_processOutgoingCalls"
@@ -629,7 +670,9 @@
android:description="@string/permgroupdesc_microphone"
android:priority="600" />
- <!-- Allows an application to record audio. -->
+ <!-- Allows an application to record audio.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.RECORD_AUDIO"
android:permissionGroup="android.permission-group.MICROPHONE"
android:label="@string/permlab_recordAudio"
@@ -655,7 +698,9 @@
&lt;uses-feature&gt;}</a> manifest element for <em>all</em> camera features.
If you do not require all camera features or can properly operate if a camera
is not available, then you must modify your manifest as appropriate in order to
- install on devices that don't support all camera features.</p> -->
+ install on devices that don't support all camera features.</p>
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.CAMERA"
android:permissionGroup="android.permission-group.CAMERA"
android:label="@string/permlab_camera"
@@ -676,14 +721,17 @@
android:priority="800" />
<!-- Allows an application to access data from sensors that the user uses to
- measure what is happening inside his/her body, such as heart rate. -->
+ measure what is happening inside his/her body, such as heart rate.
+ <p>Protection level: dangerous -->
<permission android:name="android.permission.BODY_SENSORS"
android:permissionGroup="android.permission-group.SENSORS"
android:label="@string/permlab_bodySensors"
android:description="@string/permdesc_bodySensors"
android:protectionLevel="dangerous" />
- <!-- Allows an app to use fingerprint hardware. -->
+ <!-- Allows an app to use fingerprint hardware.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.USE_FINGERPRINT"
android:permissionGroup="android.permission-group.SENSORS"
android:label="@string/permlab_useFingerprint"
@@ -768,7 +816,9 @@
<!-- =============================================================== -->
<eat-comment />
- <!-- Allows an application to broadcast an Intent to set an alarm for the user. -->
+ <!-- Allows an application to broadcast an Intent to set an alarm for the user.
+ <p>Protection level: normal
+ -->
<permission android:name="com.android.alarm.permission.SET_ALARM"
android:label="@string/permlab_setAlarm"
android:description="@string/permdesc_setAlarm"
@@ -779,11 +829,15 @@
<!-- =============================================================== -->
<eat-comment />
- <!-- Allows an application to modify and remove existing voicemails in the system -->
+ <!-- Allows an application to modify and remove existing voicemails in the system
+ <p>Protection level: system|signature
+ -->
<permission android:name="com.android.voicemail.permission.WRITE_VOICEMAIL"
android:protectionLevel="system|signature" />
- <!-- Allows an application to read voicemails in the system. -->
+ <!-- Allows an application to read voicemails in the system.
+ <p>Protection level: system|signature
+ -->
<permission android:name="com.android.voicemail.permission.READ_VOICEMAIL"
android:protectionLevel="system|signature" />
@@ -792,7 +846,9 @@
<!-- ======================================= -->
<eat-comment />
- <!-- Allows an application to access extra location provider commands -->
+ <!-- Allows an application to access extra location provider commands
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"
android:label="@string/permlab_accessLocationExtraCommands"
android:description="@string/permdesc_accessLocationExtraCommands"
@@ -816,7 +872,10 @@
android:protectionLevel="signature|system" />
<uses-permission android:name="android.permission.LOCATION_HARDWARE"/>
- <!-- Allows an application to create mock location providers for testing. -->
+ <!-- @SystemApi Allows an application to create mock location providers for testing.
+ <p>Protection level: signature
+ @hide
+ -->
<permission android:name="android.permission.ACCESS_MOCK_LOCATION"
android:protectionLevel="signature" />
@@ -825,25 +884,33 @@
<!-- ======================================= -->
<eat-comment />
- <!-- Allows applications to open network sockets. -->
+ <!-- Allows applications to open network sockets.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.INTERNET"
android:description="@string/permdesc_createNetworkSockets"
android:label="@string/permlab_createNetworkSockets"
android:protectionLevel="normal" />
- <!-- Allows applications to access information about networks -->
+ <!-- Allows applications to access information about networks
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.ACCESS_NETWORK_STATE"
android:description="@string/permdesc_accessNetworkState"
android:label="@string/permlab_accessNetworkState"
android:protectionLevel="normal" />
- <!-- Allows applications to access information about Wi-Fi networks -->
+ <!-- Allows applications to access information about Wi-Fi networks.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.ACCESS_WIFI_STATE"
android:description="@string/permdesc_accessWifiState"
android:label="@string/permlab_accessWifiState"
android:protectionLevel="normal" />
- <!-- Allows applications to change Wi-Fi connectivity state -->
+ <!-- Allows applications to change Wi-Fi connectivity state.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.CHANGE_WIFI_STATE"
android:description="@string/permdesc_changeWifiState"
android:label="@string/permlab_changeWifiState"
@@ -890,13 +957,17 @@
<!-- ======================================= -->
<eat-comment />
- <!-- Allows applications to connect to paired bluetooth devices -->
+ <!-- Allows applications to connect to paired bluetooth devices.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.BLUETOOTH"
android:description="@string/permdesc_bluetooth"
android:label="@string/permlab_bluetooth"
android:protectionLevel="normal" />
- <!-- Allows applications to discover and pair bluetooth devices -->
+ <!-- Allows applications to discover and pair bluetooth devices.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.BLUETOOTH_ADMIN"
android:description="@string/permdesc_bluetoothAdmin"
android:label="@string/permlab_bluetoothAdmin"
@@ -920,7 +991,9 @@
<permission android:name="android.permission.BLUETOOTH_STACK"
android:protectionLevel="signature" />
- <!-- Allows applications to perform I/O operations over NFC -->
+ <!-- Allows applications to perform I/O operations over NFC.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.NFC"
android:description="@string/permdesc_nfc"
android:label="@string/permlab_nfc"
@@ -951,16 +1024,9 @@
<!-- ================================== -->
<eat-comment />
- <!-- Permissions for direct access to the accounts managed
- by the Account Manager. -->
- <permission-group android:name="android.permission-group.ACCOUNTS"
- android:label="@string/permgrouplab_accounts"
- android:icon="@drawable/perm_group_accounts"
- android:description="@string/permgroupdesc_accounts"
- android:permissionGroupFlags="personalInfo"
- android:priority="1000" />
-
- <!-- Allows access to the list of accounts in the Accounts Service -->
+ <!-- Allows access to the list of accounts in the Accounts Service.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.GET_ACCOUNTS"
android:permissionGroup="android.permission-group.CONTACTS"
android:protectionLevel="normal"
@@ -970,7 +1036,6 @@
<!-- @SystemApi Allows applications to call into AccountAuthenticators.
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.ACCOUNT_MANAGER"
- android:permissionGroup="android.permission-group.ACCOUNTS"
android:protectionLevel="signature" />
<!-- ================================== -->
@@ -978,32 +1043,42 @@
<!-- ================================== -->
<eat-comment />
- <!-- Allows applications to enter Wi-Fi Multicast mode -->
+ <!-- Allows applications to enter Wi-Fi Multicast mode.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"
android:description="@string/permdesc_changeWifiMulticastState"
android:label="@string/permlab_changeWifiMulticastState"
android:protectionLevel="normal" />
- <!-- Allows access to the vibrator -->
+ <!-- Allows access to the vibrator.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.VIBRATE"
android:label="@string/permlab_vibrate"
android:description="@string/permdesc_vibrate"
android:protectionLevel="normal" />
- <!-- Allows access to the flashlight -->
+ <!-- Allows access to the flashlight.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.FLASHLIGHT"
android:label="@string/permlab_flashlight"
android:description="@string/permdesc_flashlight"
android:protectionLevel="normal" />
<!-- Allows using PowerManager WakeLocks to keep processor from sleeping or screen
- from dimming -->
+ from dimming.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.WAKE_LOCK"
android:label="@string/permlab_wakeLock"
android:description="@string/permdesc_wakeLock"
android:protectionLevel="normal" />
- <!-- Allows using the device's IR transmitter, if available -->
+ <!-- Allows using the device's IR transmitter, if available.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.TRANSMIT_IR"
android:label="@string/permlab_transmitIr"
android:description="@string/permdesc_transmitIr"
@@ -1014,7 +1089,9 @@
<!-- ==================================================== -->
<eat-comment />
- <!-- Allows an application to modify global audio settings -->
+ <!-- Allows an application to modify global audio settings.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"
android:label="@string/permlab_modifyAudioSettings"
android:description="@string/permdesc_modifyAudioSettings"
@@ -1036,8 +1113,10 @@
<permission android:name="android.permission.ACCESS_MTP"
android:protectionLevel="signature|system" />
- <!-- Allows access to hardware peripherals. Intended only for hardware testing.
- <p>Not for use by third-party applications. -->
+ <!-- @SystemApi Allows access to hardware peripherals. Intended only for hardware testing.
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.HARDWARE_TEST"
android:protectionLevel="signature" />
@@ -1146,7 +1225,9 @@
android:protectionLevel="system|signature" />
<!-- Must be required by a {@link android.telecom.InCallService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: system|signature
+ -->
<permission android:name="android.permission.BIND_INCALL_SERVICE"
android:protectionLevel="system|signature" />
@@ -1160,7 +1241,9 @@
android:protectionLevel="system|signature" />
<!-- Must be required by a {@link android.telecom.ConnectionService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: system|signature
+ -->
<permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
android:protectionLevel="system|signature" />
@@ -1185,7 +1268,9 @@
android:protectionLevel="signature|system" />
<!-- Allows an application to manage access to documents, usually as part
- of a document picker. -->
+ of a document picker.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.MANAGE_DOCUMENTS"
android:protectionLevel="signature" />
@@ -1194,7 +1279,9 @@
<!-- ================================== -->
<eat-comment />
- <!-- Allows applications to disable the keyguard if it is not secure. -->
+ <!-- Allows applications to disable the keyguard if it is not secure.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.DISABLE_KEYGUARD"
android:description="@string/permdesc_disableKeyguard"
android:label="@string/permlab_disableKeyguard"
@@ -1261,7 +1348,9 @@
<permission android:name="android.permission.GET_DETAILED_TASKS"
android:protectionLevel="signature" />
- <!-- Allows an application to change the Z-order of tasks -->
+ <!-- Allows an application to change the Z-order of tasks.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.REORDER_TASKS"
android:label="@string/permlab_reorderTasks"
android:description="@string/permdesc_reorderTasks"
@@ -1289,7 +1378,9 @@
android:protectionLevel="normal" />
<!-- Allows an application to call
- {@link android.app.ActivityManager#killBackgroundProcesses}. -->
+ {@link android.app.ActivityManager#killBackgroundProcesses}.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"
android:label="@string/permlab_killBackgroundProcesses"
android:description="@string/permdesc_killBackgroundProcesses"
@@ -1313,20 +1404,24 @@
<permission android:name="android.permission.SYSTEM_ALERT_WINDOW"
android:label="@string/permlab_systemAlertWindow"
android:description="@string/permdesc_systemAlertWindow"
- android:protectionLevel="dangerous" />
+ android:protectionLevel="signature|system|appop|pre23" />
<!-- ================================== -->
<!-- Permissions affecting the system wallpaper -->
<!-- ================================== -->
<eat-comment />
- <!-- Allows applications to set the wallpaper -->
+ <!-- Allows applications to set the wallpaper.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.SET_WALLPAPER"
android:label="@string/permlab_setWallpaper"
android:description="@string/permdesc_setWallpaper"
android:protectionLevel="normal" />
- <!-- Allows applications to set the wallpaper hints -->
+ <!-- Allows applications to set the wallpaper hints.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.SET_WALLPAPER_HINTS"
android:label="@string/permlab_setWallpaperHints"
android:description="@string/permdesc_setWallpaperHints"
@@ -1342,7 +1437,9 @@
<permission android:name="android.permission.SET_TIME"
android:protectionLevel="signature|system" />
- <!-- Allows applications to set the system time zone -->
+ <!-- Allows applications to set the system time zone.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.SET_TIME_ZONE"
android:label="@string/permlab_setTimeZone"
android:description="@string/permdesc_setTimeZone"
@@ -1353,7 +1450,9 @@
<!-- ==================================================== -->
<eat-comment />
- <!-- Allows an application to expand or collapse the status bar. -->
+ <!-- Allows an application to expand or collapse the status bar.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.EXPAND_STATUS_BAR"
android:label="@string/permlab_expandStatusBar"
android:description="@string/permdesc_expandStatusBar"
@@ -1364,13 +1463,17 @@
<!-- ============================================================== -->
<eat-comment />
- <!-- Allows an application to install a shortcut in Launcher -->
+ <!-- Allows an application to install a shortcut in Launcher.
+ <p>Protection level: normal
+ -->
<permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"
android:label="@string/permlab_install_shortcut"
android:description="@string/permdesc_install_shortcut"
android:protectionLevel="normal"/>
- <!-- Allows an application to uninstall a shortcut in Launcher -->
+ <!-- Allows an application to uninstall a shortcut in Launcher.
+ <p>Protection level: normal
+ -->
<permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"
android:label="@string/permlab_uninstall_shortcut"
android:description="@string/permdesc_uninstall_shortcut"
@@ -1381,19 +1484,25 @@
<!-- ==================================================== -->
<eat-comment />
- <!-- Allows applications to read the sync settings -->
+ <!-- Allows applications to read the sync settings.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.READ_SYNC_SETTINGS"
android:description="@string/permdesc_readSyncSettings"
android:label="@string/permlab_readSyncSettings"
android:protectionLevel="normal" />
- <!-- Allows applications to write the sync settings -->
+ <!-- Allows applications to write the sync settings.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.WRITE_SYNC_SETTINGS"
android:description="@string/permdesc_writeSyncSettings"
android:label="@string/permlab_writeSyncSettings"
android:protectionLevel="normal" />
- <!-- Allows applications to read the sync stats -->
+ <!-- Allows applications to read the sync stats.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.READ_SYNC_STATS"
android:description="@string/permdesc_readSyncStats"
android:label="@string/permlab_readSyncStats"
@@ -1451,7 +1560,9 @@
android:description="@string/permdesc_persistentActivity"
android:protectionLevel="normal" />
- <!-- Allows an application to find out the space used by any package. -->
+ <!-- Allows an application to find out the space used by any package.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.GET_PACKAGE_SIZE"
android:label="@string/permlab_getPackageSize"
android:description="@string/permdesc_getPackageSize"
@@ -1473,7 +1584,9 @@
system to start and allowing applications to have themselves
running without the user being aware of them. As such, you must
explicitly declare your use of this facility to make that visible
- to the user. -->
+ to the user.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"
android:label="@string/permlab_receiveBootCompleted"
android:description="@string/permdesc_receiveBootCompleted"
@@ -1482,7 +1595,9 @@
<!-- Allows an application to broadcast sticky intents. These are
broadcasts whose data is held by the system after being finished,
so that clients can quickly retrieve that data without having
- to wait for the next broadcast. -->
+ to wait for the next broadcast.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.BROADCAST_STICKY"
android:label="@string/permlab_broadcastSticky"
android:description="@string/permdesc_broadcastSticky"
@@ -1528,14 +1643,18 @@
<permission android:name="android.permission.WRITE_APN_SETTINGS"
android:protectionLevel="signature|system" />
- <!-- Allows applications to change network connectivity state -->
+ <!-- Allows applications to change network connectivity state.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.CHANGE_NETWORK_STATE"
android:description="@string/permdesc_changeNetworkState"
android:label="@string/permlab_changeNetworkState"
android:protectionLevel="normal" />
<!-- Allows an application to clear the caches of all installed
- applications on the device. -->
+ applications on the device.
+ <p>Protection level: system|signature
+ -->
<permission android:name="android.permission.CLEAR_APP_CACHE"
android:protectionLevel="signatureOrSystem" />
@@ -1634,9 +1753,11 @@
<permission android:name="android.permission.STATUS_BAR_SERVICE"
android:protectionLevel="signature" />
- <!-- Allows an application to force a BACK operation on whatever is the
+ <!-- @SystemApi Allows an application to force a BACK operation on whatever is the
top activity.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.FORCE_BACK"
android:protectionLevel="signature" />
@@ -1654,15 +1775,19 @@
<permission android:name="android.permission.UPDATE_APP_OPS_STATS"
android:protectionLevel="signature|system" />
- <!-- Allows an application to open windows that are for use by parts
+ <!-- @SystemApi Allows an application to open windows that are for use by parts
of the system user interface.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"
android:protectionLevel="signature" />
- <!-- Allows an application to manage (create, destroy,
+ <!-- @SystemApi Allows an application to manage (create, destroy,
Z-order) application tokens in the window manager.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.MANAGE_APP_TOKENS"
android:protectionLevel="signature" />
@@ -1671,10 +1796,12 @@
<permission android:name="android.permission.FREEZE_SCREEN"
android:protectionLevel="signature" />
- <!-- Allows an application to inject user events (keys, touch, trackball)
+ <!-- @SystemApi Allows an application to inject user events (keys, touch, trackball)
into the event stream and deliver them to ANY window. Without this
permission, you can only deliver events to windows in your own process.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.INJECT_EVENTS"
android:protectionLevel="signature" />
@@ -1695,10 +1822,12 @@
<permission android:name="android.permission.TEMPORARY_ENABLE_ACCESSIBILITY"
android:protectionLevel="signature" />
- <!-- Allows an application to watch and control how activities are
+ <!-- @SystemApi Allows an application to watch and control how activities are
started globally in the system. Only for is in debugging
(usually the monkey command).
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.SET_ACTIVITY_WATCHER"
android:protectionLevel="signature" />
@@ -1716,9 +1845,11 @@
<permission android:name="android.permission.STOP_APP_SWITCHES"
android:protectionLevel="signature|system" />
- <!-- Allows an application to retrieve private information about
+ <!-- @SystemApi Allows an application to retrieve private information about
the current top activity, such as any assist context it can provide.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"
android:protectionLevel="signature" />
@@ -1730,28 +1861,38 @@
android:protectionLevel="signature" />
<!-- Must be required by an {@link android.inputmethodservice.InputMethodService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_INPUT_METHOD"
android:protectionLevel="signature" />
<!-- Must be required by an {@link android.media.midi.MidiDeviceService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_MIDI_DEVICE_SERVICE"
android:protectionLevel="signature" />
<!-- Must be required by an {@link android.accessibilityservice.AccessibilityService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:protectionLevel="signature" />
<!-- Must be required by a {@link android.printservice.PrintService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_PRINT_SERVICE"
android:protectionLevel="signature" />
<!-- Must be required by a {@link android.nfc.cardemulation.HostApduService}
or {@link android.nfc.cardemulation.OffHostApduService} to ensure that only
- the system can bind to it. -->
+ the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_NFC_SERVICE"
android:protectionLevel="signature" />
@@ -1761,22 +1902,30 @@
android:protectionLevel="signature" />
<!-- Must be required by a TextService (e.g. SpellCheckerService)
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_TEXT_SERVICE"
android:protectionLevel="signature" />
<!-- Must be required by a {@link android.net.VpnService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_VPN_SERVICE"
android:protectionLevel="signature" />
<!-- Must be required by a {@link android.service.wallpaper.WallpaperService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: system|signature
+ -->
<permission android:name="android.permission.BIND_WALLPAPER"
android:protectionLevel="signature|system" />
<!-- Must be required by a {@link android.service.voice.VoiceInteractionService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_VOICE_INTERACTION"
android:protectionLevel="signature" />
@@ -1793,7 +1942,9 @@
android:protectionLevel="signature" />
<!-- Must be required by a {@link android.media.tv.TvInputService}
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_TV_INPUT"
android:protectionLevel="signature|system" />
@@ -1810,7 +1961,9 @@
android:protectionLevel="signature" />
<!-- Must be required by device administration receiver, to ensure that only the
- system can interact with it. -->
+ system can interact with it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_DEVICE_ADMIN"
android:protectionLevel="signature" />
@@ -1820,14 +1973,18 @@
<permission android:name="android.permission.MANAGE_DEVICE_ADMINS"
android:protectionLevel="signature|system" />
- <!-- Allows low-level access to setting the orientation (actually
+ <!-- @SystemApi Allows low-level access to setting the orientation (actually
rotation) of the screen.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.SET_ORIENTATION"
android:protectionLevel="signature" />
- <!-- Allows low-level access to setting the pointer speed.
- <p>Not for use by third-party applications. -->
+ <!-- @SystemApi Allows low-level access to setting the pointer speed.
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.SET_POINTER_SPEED"
android:protectionLevel="signature" />
@@ -1845,7 +2002,9 @@
<!-- Allows an application to request installing packages. Apps
targeting APIs greater than 22 must hold this permission in
- order to use {@link android.content.Intent#ACTION_INSTALL_PACKAGE}.-->
+ order to use {@link android.content.Intent#ACTION_INSTALL_PACKAGE}.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"
android:label="@string/permlab_requestInstallPackages"
android:description="@string/permdesc_requestInstallPackages"
@@ -1856,8 +2015,10 @@
<permission android:name="android.permission.INSTALL_PACKAGES"
android:protectionLevel="signature|system" />
- <!-- Allows an application to clear user data.
- <p>Not for use by third-party applications. -->
+ <!-- @SystemApi Allows an application to clear user data.
+ <p>Not for use by third-party applications
+ @hide
+ -->
<permission android:name="android.permission.CLEAR_APP_USER_DATA"
android:protectionLevel="signature" />
@@ -1890,8 +2051,10 @@
<permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"
android:protectionLevel="signatureOrSystem" />
- <!-- Allows an application to use SurfaceFlinger's low level features.
- <p>Not for use by third-party applications. -->
+ <!-- @SystemApi Allows an application to use SurfaceFlinger's low level features.
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.ACCESS_SURFACE_FLINGER"
android:protectionLevel="signature" />
@@ -1957,8 +2120,10 @@
<permission android:name="android.permission.MEDIA_CONTENT_CONTROL"
android:protectionLevel="signature|system" />
- <!-- Required to be able to disable the device (very dangerous!).
- <p>Not for use by third-party applications.. -->
+ <!-- @SystemApi Required to be able to disable the device (very dangerous!).
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.BRICK"
android:protectionLevel="signature" />
@@ -1967,9 +2132,11 @@
<permission android:name="android.permission.REBOOT"
android:protectionLevel="signature|system" />
- <!-- Allows low-level access to power management.
- <p>Not for use by third-party applications. -->
- <permission android:name="android.permission.DEVICE_POWER"
+ <!-- @SystemApi Allows low-level access to power management.
+ <p>Not for use by third-party applications.
+ @hide
+ -->
+ <permission android:name="android.permission.DEVICE_POWER"
android:protectionLevel="signature" />
<!-- Allows access to the PowerManager.userActivity function.
@@ -1983,23 +2150,27 @@
<!-- Run as a manufacturer test application, running as the root user.
Only available when the device is running in manufacturer test mode.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ -->
<permission android:name="android.permission.FACTORY_TEST"
android:protectionLevel="signature" />
<!-- Allows an application to broadcast a notification that an application
package has been removed.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ -->
<permission android:name="android.permission.BROADCAST_PACKAGE_REMOVED"
android:protectionLevel="signature" />
<!-- Allows an application to broadcast an SMS receipt notification.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ -->
<permission android:name="android.permission.BROADCAST_SMS"
android:protectionLevel="signature" />
<!-- Allows an application to broadcast a WAP PUSH receipt notification.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ -->
<permission android:name="android.permission.BROADCAST_WAP_PUSH"
android:protectionLevel="signature" />
@@ -2242,7 +2413,9 @@
<permission android:name="android.permission.ACCESS_NOTIFICATIONS"
android:protectionLevel="signature|system" />
- <!-- Marker permission for applications that wish to access notification policy. -->
+ <!-- Marker permission for applications that wish to access notification policy.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY"
android:description="@string/permdesc_access_notification_policy"
android:label="@string/permlab_access_notification_policy"
@@ -2286,13 +2459,17 @@
<!-- Must be required by an {@link
android.service.notification.NotificationListenerService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
android:protectionLevel="signature" />
<!-- Must be required by a {@link
android.service.chooser.ChooserTargetService}, to ensure that
- only the system can bind to it. -->
+ only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_CHOOSER_TARGET_SERVICE"
android:protectionLevel="signature" />
@@ -2304,7 +2481,9 @@
android:protectionLevel="signature" />
<!-- Must be required by an {@link android.service.dreams.DreamService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_DREAM_SERVICE"
android:protectionLevel="signature" />
@@ -2359,7 +2538,9 @@
<!-- The system process that is allowed to bind to services in carrier apps will
have this permission. Carrier apps should use this permission to protect
- their services that only the system is allowed to bind to. -->
+ their services that only the system is allowed to bind to.
+ <p>Protection level: system|signature
+ -->
<permission android:name="android.permission.BIND_CARRIER_SERVICES"
android:label="@string/permlab_bindCarrierServices"
android:description="@string/permdesc_bindCarrierServices"
diff --git a/core/res/res/drawable-hdpi/perm_group_accounts.png b/core/res/res/drawable-hdpi/perm_group_accounts.png
deleted file mode 100644
index 5ac28e7..0000000
--- a/core/res/res/drawable-hdpi/perm_group_accounts.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_accounts.png b/core/res/res/drawable-mdpi/perm_group_accounts.png
deleted file mode 100644
index ce4e683..0000000
--- a/core/res/res/drawable-mdpi/perm_group_accounts.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_accounts.png b/core/res/res/drawable-xhdpi/perm_group_accounts.png
deleted file mode 100644
index ca622e9..0000000
--- a/core/res/res/drawable-xhdpi/perm_group_accounts.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_accounts.png b/core/res/res/drawable-xxhdpi/ic_perm_group_accounts.png
deleted file mode 100644
index f30fcd4..0000000
--- a/core/res/res/drawable-xxhdpi/ic_perm_group_accounts.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_storage.png b/core/res/res/drawable-xxhdpi/ic_perm_group_storage.png
deleted file mode 100644
index d3937db..0000000
--- a/core/res/res/drawable-xxhdpi/ic_perm_group_storage.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_accounts.png b/core/res/res/drawable-xxhdpi/perm_group_accounts.png
deleted file mode 100644
index 2fc3baa..0000000
--- a/core/res/res/drawable-xxhdpi/perm_group_accounts.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/perm_group_accounts.png b/core/res/res/drawable-xxxhdpi/perm_group_accounts.png
deleted file mode 100644
index 1d9db83..0000000
--- a/core/res/res/drawable-xxxhdpi/perm_group_accounts.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/perm_group_storage.xml b/core/res/res/drawable/perm_group_storage.xml
index 65da1f1..62131da 100644
--- a/core/res/res/drawable/perm_group_storage.xml
+++ b/core/res/res/drawable/perm_group_storage.xml
@@ -16,9 +16,12 @@ Copyright (C) 2015 The Android Open Source Project
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
<path
- android:pathData="M20,8H8c-2.2,0 -4,1.8 -4,4l0,24c0,2.2 1.8,4 4,4h32c2.2,0 4,-1.8 4,-4V16c0,-2.2 -1.8,-4 -4,-4H24L20,8z"
- android:fillColor="#FFFFFF"/>
+ android:fillColor="#FF000000"
+ android:pathData="M0,0h48v48H0z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M27,9c2.2,0 4,-1.8 4,-4s-1.8,-4 -4,-4 -4,1.8 -4,4 1.8,4 4,4zm-7.2,27.8l1.9,-8.8 4.3,4v12h4V28.9l-4.1,-4.1 1.2,-6C29.7,22 33.6,24 38,24v-4c-3.7,0 -6.9,-2 -8.7,-4.9l-1.9,-3.2c-0.7,-1.2 -2,-1.9 -3.4,-1.9 -0.5,0 -1,0.1 -1.5,0.3L12,14.6V24h4v-6.7l3.5,-1.4L16.4,32l-9.8,-1.9 -0.8,3.9s14,2.7 14,2.8z"/>
</vector>
diff --git a/core/res/res/layout-land/time_picker_material.xml b/core/res/res/layout-land/time_picker_material.xml
index 2fa2054..2473e87 100644
--- a/core/res/res/layout-land/time_picker_material.xml
+++ b/core/res/res/layout-land/time_picker_material.xml
@@ -21,7 +21,7 @@
android:layoutDirection="ltr">
<!-- Provides a background for the time layout that extends into the button bar area. -->
- <View
+ <com.android.internal.widget.DrawingSpace
android:id="@+id/time_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
diff --git a/core/res/res/layout/date_picker_view_animator_material.xml b/core/res/res/layout/date_picker_view_animator_material.xml
index e863b28..04647b1 100644
--- a/core/res/res/layout/date_picker_view_animator_material.xml
+++ b/core/res/res/layout/date_picker_view_animator_material.xml
@@ -32,6 +32,7 @@
<android.widget.YearPickerView
android:id="@+id/date_picker_year_picker"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="match_parent"
+ android:scrollIndicators="bottom" />
</com.android.internal.widget.DialogViewAnimator>
diff --git a/core/res/res/layout/floating_popup_menu_button.xml b/core/res/res/layout/floating_popup_menu_button.xml
index 1b58ce5..482f91f 100644
--- a/core/res/res/layout/floating_popup_menu_button.xml
+++ b/core/res/res/layout/floating_popup_menu_button.xml
@@ -18,7 +18,8 @@
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:minWidth="@dimen/floating_toolbar_menu_button_side_padding"
+ android:minWidth="@dimen/floating_toolbar_menu_button_minimum_width"
+ android:minHeight="@dimen/floating_toolbar_height"
android:paddingStart="@dimen/floating_toolbar_menu_button_side_padding"
android:paddingEnd="@dimen/floating_toolbar_menu_button_side_padding"
android:paddingTop="0dp"
diff --git a/core/res/res/layout/year_label_text_view.xml b/core/res/res/layout/year_label_text_view.xml
index 6240c4b..3ea719d 100644
--- a/core/res/res/layout/year_label_text_view.xml
+++ b/core/res/res/layout/year_label_text_view.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/month_text_view"
+ android:id="@id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/listPreferredItemHeightSmall"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index d244f53..0238fb7 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"neem foto\'s en neem video op"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Foon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"maak en bestuur foonoproepe"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensors"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"toeganginligting oor jou lewenstekens en fisieke aktiwiteit"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Liggaamsensors"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"kry toegang tot sensordata oor jou lewenstekens"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Haal venster-inhoud op"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Ondersoek die inhoud van \'n venster waarmee jy interaksie het."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Skakel Verken deur raak aan"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Laat die program toe om MMS-boodskappe te ontvang en te verwerk. Dit beteken dat die program boodskappe wat na jou toestel gestuur is kan monitor of uitvee, sonder dat jy dit gesien het."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lees seluitsending-boodskappe"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Laat die program toe om seluitsending-boodskappe te lees wat deur jou toestel ontvang word. Seluitsending-waarskuwings word in sommige plekke afgelewer om jou van noodsituasies te waarsku. Kwaadwillige programme mag inmeng met die prestasie of die werking van jou toestel wanneer \'n noodgeval se seluitsending ontvang word."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Jou rekeninge"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Kry toegang tot beskikbare rekeninge."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lees ingetekende nuus"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Laat die program toe om details oor die tans gesinkroniseerde strome te kry."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"stuur en bekyk SMS-boodskappe"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 205a89a..bb03f82 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ስዕሎች ያንሱ እና ቪዲዮ ይቅረጹ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ስልክ"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"የስልክ ጥሪዎች ያድርጉ እና ያስተዳድሩ"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"አነፍናፊዎች"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"ስለእርስዎ አስፈላጊ ምልክቶች እና አካላዊ እንቅስቃሴ መረጃ ይድረሱ"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"የሰውነት ዳሳሾች"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ስለአስፈላጊ ምልክቶችዎ ያሉ የዳሳሽ ውሂብ ይድረሱ"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"የመስኮት ይዘት ሰርስረው ያውጡ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"መስተጋበር የሚፈጥሩት የመስኮት ይዘት ይመርምሩ።"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"በመንካት ያስሱን ያብሩ"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"መተግበሪያው የኤም.ኤም.ኤስ. መልዕክቶችን እንዲያነብ እና እንዲያካሂድ ይፈቅዳል። ይህ ማለት መተግበሪያው ወደ መሳሪያህ የተላኩ መልዕክቶችን ላንተ ሳያሳይህ ሊቆጣጠር ወይም ሊሰርዝ ይችላል።"</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"የህዋስ ስርጭት መልዕክቶችን አንብብ"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"መሣሪያህ የህዋስ ስርጭት መልዕክቶች ሲቀበል መተግበሪያው እንዲያነበው ይፈቅድለታል። የህዋስ ስርጭት ማንቂያዎች አስቸኳይ ሁኔታዎች ሲያጋጥሙ አንዳንድ አካባቢዎች ላይ የሚላኩ ናቸው። የህዋስ ስርጭት ሲደርስ ተንኮል አዘል መተግበሪያዎች በመሣሪያህ አፈጻጸም ወይም አሰራር ላይ ጣልቃ ሊገቡ ይችላሉ።"</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"መለያዎችዎ"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">" ለተገኙት መለያዎች ድረስ"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"የምዝገባ መግቦች አንበብ"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ስለ አሁኑ ጊዜ አስምር ምላሾች ዝርዝሮች ለማግኘት ለመተግበሪያው ይፈቅዳሉ።"</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"የኤስኤምኤስ መልዕክቶችን ይላኩና ይመልከቱ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 10f172f..34fbe69 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -246,8 +246,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"التقاط صور وتسجيل فيديو"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"الهاتف"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"إجراء مكالمات هاتفية وإدارتها"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"أجهزة الاستشعار"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"الوصول إلى المعلومات عن علاماتك الحيوية ونشاطك البدني"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"أجهزة استشعار الجسم"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"الوصول إلى بيانات المستشعر حول علاماتك الحيوية"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"استرداد محتوى النافذة"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"فحص محتوى نافذة يتم التفاعل معها."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"تشغيل الاستكشاف باللمس"</string>
@@ -274,8 +274,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"للسماح للتطبيق بتلقي ومعالجة رسائل الوسائط المتعددة. وهذا يعني أنه يمكن للتطبيق مراقبة الرسائل التي يتم إرسالها لجهازك أو حذفها بدون عرضها لك."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"قراءة رسائل بث الخلية"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"السماح للتطبيق بقراءة رسائل بث الخلية التي يتلقاها هذا الجهاز. يتم تسليم اشعارات بث الخلية في بعض المواقع لتحذيرك من حالات طارئة. يمكن أن تتداخل التطبيقات الضارة مع أداء أو تشغيل الجهاز عندما يتم تلقي بث خلية طارئ."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"حساباتك"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"الوصول إلى الحسابات المتاحة."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"قراءة الخلاصات المشتركة"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"للسماح للتطبيق بالحصول على تفاصيل حول الخلاصات المتزامنة في الوقت الحالي."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"‏إرسال رسائل قصيرة SMS وعرضها"</string>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index 35f6479..0afec19 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"şəkil çəkin və video yazın"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"telefon zəngləri edin və onları idarə edin"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorlar"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"həyati əlamətlər və fiziki aktivliyiniz haqqında məlumatlara daxil olun"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Bədən Sensorları"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"Həyati əlamətlər haqqında sensor dataya daxil olun"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pəncərənin məzmununu əldə edin"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Əlaqədə olduğunuz pəncərənin məzmununu nəzərdən keçirin."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Toxunaraq Kəşf et funksiyasını yandırın"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Tətbiqə MMS mesajlarını qəbul və emal üçün imkan verir. Bu o deməkdir ki, bu tətbiq sizə göstərmədən cihazınıza göndərilən mesajları silə bilər."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"mobil yayım mesajlarını oxuyur"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Tətbiqə sizin telefonunuz tərəfindən alınmış yayım mesajlarını oxuma icazəsi verir. Telefon yayımı bəzi məkanlarda olan fövqəladə hadisələrlə bağlı sizi xəbərdar etmək üçün qəbul edilir. Zərərli tətbiqlər fövqəladə mobil yayım qəbul edildiyi zaman telefonunun performansına və əməliyyatına müdaxilə edə bilər."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Hesablarınız"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Əlçatımlı hesablara daxil olun."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"abunə olunmuş xəbərləri oxuyur"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Tətbiqə hazırda sinxron lentlər haqqında ətraflı məlumat almaq üçün imkan verir."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"göndərin və SMS mesajlarına baxın"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 9a771ea..7504637 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"правене на снимки и запис на видеоклипове"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"извършване и управление на телефонни обаждания"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Сензори"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"достъп до информацията за вашите жизнени показатели и физическа активност"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Телесни сензори"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"достъп до сензорните данни за жизнените ви показатели"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Извличане на съдържанието от прозореца"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Инспектиране на съдържанието на прозорец, с който взаимодействате."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Включване на изследването чрез докосване"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Разрешава на приложението да получава и обработва MMS съобщения. Това означава, че то може да наблюдава или изтрива изпратените до устройството ви, без да ви ги покаже."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"четене на съобщения с клетъчно излъчване"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Разрешава на приложението да чете съобщения с клетъчно излъчване, получени от устройството ви. Сигналите с клетъчно излъчване се получават на някои местоположения, за да ви предупредят за спешни ситуации. Злонамерените приложения могат да възпрепятстват изпълнението или работата на устройството ви при получаване на такова спешно излъчване."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Вашите профили"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Достъп до наличните профили."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"четене на емисиите с абонамент"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Разрешава на приложението да получи подробности за текущо синхронизираните емисии."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"изпращане и преглед на SMS съобщения"</string>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index 9cda852..5e33789 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ছবি তুলুন এবং ভিডিও রেকর্ড করুন"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ফোন"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ফোন কলগুলি করুন এবং পরিচালনা করুন"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"সেন্সরগুলি"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"আপনার গুরুত্বপূর্ণ লক্ষণ এবং শারীরিক ক্রিয়াকলাপের সম্পর্কে তথ্য অ্যাক্সেস করুন"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"বডি সেন্সরগুলি"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"আপনার অত্যাবশ্যক লক্ষণগুলির সম্পর্কে সেন্সর ডেটা অ্যাক্সেস করে"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"উইন্ডোর সামগ্রী পুনরুদ্ধার করে"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"আপনি ইন্টারঅ্যাক্ট করছেন এমন একটি উইন্ডোর সামগ্রীকে সযত্নে নিরীক্ষণ করে৷"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"স্পর্শের মাধ্যমে অন্বেষণ করা চালু করুন"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"অ্যাপ্লিকেশানটিকে MMS বার্তা প্রাপ্ত করার এবং প্রক্রিয়া করার অনুমতি দেয়৷ এর মানে হল অ্যাপ্লিকেশানটি আপনার ডিভাইস থেকে পাঠানো বার্তাগুলিকে পর্যবেক্ষণ করতে পারে এবং মুছতে পারে সেগুলিকে আপনাকে না দেখিয়ে৷"</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"সেল সম্প্রচার বার্তা পড়ুন"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"আপনার ডিভাইস দ্বারা প্রাপ্ত সেল সম্প্রচার পড়তে অ্যাপ্লিকেশানটিকে অনুমতি দেয়৷ কয়েকটি স্থানে আপনাকে জরুরি অবস্থার জন্য সতর্ক করতে জরুরি সতর্কতাগুলি বিতরণ করা হয়৷ যখন একটি জরুরি সেল সম্প্রচার প্রাপ্ত হয় তখন ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনার ডিভাইসের কার্য সম্পাদনা বা কার্যকলাপে প্রতিবন্ধকতার সৃষ্টি করতে পারে৷"</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"আপনার অ্যাকাউন্টগুলি"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"উপলব্ধ অ্যাকাউন্টগুলি অ্যাক্সেস করে৷"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"গ্রাহক হিসাবে নেওয়া ফিডগুলি পড়ে"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"অ্যাপ্লিকেশানকে বর্তমানে সিঙ্ক করা ফিডগুলির সম্পর্কে বিবরণ পেতে দেয়৷"</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS বার্তাগুলি পাঠান এবং দেখুন"</string>
@@ -852,7 +850,7 @@
<string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll" msgid="6876518925844129331">"সবগুলি নির্বাচন করুন"</string>
- <string name="cut" msgid="3092569408438626261">"ছেদন"</string>
+ <string name="cut" msgid="3092569408438626261">"কাটুন"</string>
<string name="copy" msgid="2681946229533511987">"অনুলিপি"</string>
<string name="paste" msgid="5629880836805036433">"আটকান"</string>
<string name="replace" msgid="5781686059063148930">"প্রতিস্থাপন করুন..."</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 0402264..45a064f 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -167,7 +167,7 @@
<string name="low_memory" product="default" msgid="3475999286680000541">"L\'emmagatzematge del telèfon és ple. Suprimeix uns quants fitxers per alliberar espai."</string>
<string name="ssl_ca_cert_warning" msgid="5848402127455021714">"És possible que la xarxa estigui supervisada"</string>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Per un tercer desconegut"</string>
- <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Administrador del perfil de la feina"</string>
+ <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Administrador del perfil professional"</string>
<string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Per <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
<string name="work_profile_deleted" msgid="5005572078641980632">"S\'ha suprimit el perfil professional"</string>
<string name="work_profile_deleted_description" msgid="6305147513054341102">"S\'ha suprimit el perfil professional perquè no s\'ha detectat cap aplicació d\'administració."</string>
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"fer fotos i vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telèfon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"fer i gestionar les trucades telefòniques"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensors"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"accedir a informació sobre els signes vitals i l\'activitat física"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensors corporals"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accedir a les dades del sensor sobre els signes vitals"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar el contingut de la finestra"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona el contingut d\'una finestra amb què estàs interaccionant."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar Exploració tàctil"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permet que l\'aplicació rebi i processi missatges MMS. Això vol dir que l\'aplicació pot controlar o suprimir missatges que s\'han enviat al teu dispositiu sense mostrar-te\'ls."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"llegir missatges de difusió mòbil"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permet que l\'aplicació llegeixi missatges de difusió mòbil rebuts pel dispositiu. Les alertes de difusió mòbil s\'entreguen en algunes ubicacions per alertar de situacions d\'emergència. És possible que les aplicacions malicioses interfereixin en el rendiment o en el funcionament del dispositiu quan es rep una difusió mòbil d\'emergència."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Comptes"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Accedeix als comptes disponibles."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"llegir els feeds als quals esteu subscrit"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permet que l\'aplicació obtingui detalls sobre els feeds sincronitzats actualment."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"envia i llegeix missatges SMS"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index c96173e..3e3a41b 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -243,9 +243,9 @@
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fotoaparát"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"pořizování fotografií a nahrávání videa"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
- <string name="permgroupdesc_phone" msgid="6234224354060641055">"uskutečňování a správa telefonních hovorů"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Senzory"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"přístup k informacím o životních funkcích a fyzické aktivitě"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"uskutečňování a spravování telefonních hovorů"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Tělesné senzory"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"přístup k údajům snímačů vašich životních funkcí"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Načíst obsah okna"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Můžete prozkoumat obsah okna, se kterým pracujete."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Zapnout funkci Prozkoumání dotykem"</string>
@@ -272,8 +272,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Umožňuje aplikaci přijmout a zpracovat zprávy MMS. Znamená to, že aplikace může sledovat zprávy odeslané do vašeho zařízení nebo je smazat, aniž by se vám zobrazily."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"čtení zpráv informačních služeb"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Umožňuje aplikaci číst zprávy informačních služeb přijaté ve vašem zařízení. Výstražná upozornění informačních služeb jsou v některých oblastech odesílána za účelem varování před výjimečnými událostmi. Škodlivé aplikace mohou narušit výkon či provoz vašeho zařízení během přijímání zpráv informačních služeb."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Vaše účty"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Přístup k dostupným účtům."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"čtení zdrojů přihlášených k odběru"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Umožňuje aplikaci získat podrobnosti o aktuálně synchronizovaných zdrojích."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"odesílání a zobrazení zpráv SMS"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 38caacb..b8cd9ab 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -229,21 +229,21 @@
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktpersoner"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"have adgang til dine kontaktpersoner"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Placering"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"adgang til enhedens placering"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"få adgang til enhedens placering"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"have adgang til din kalender"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Sms"</string>
- <string name="permgroupdesc_sms" msgid="4656988620100940350">"Send og se sms-beskeder"</string>
- <string name="permgrouplab_storage" msgid="1971118770546336966">"Lagring"</string>
- <string name="permgroupdesc_storage" msgid="637758554581589203">"Få adgang til billeder, medier og filer på din enhed"</string>
+ <string name="permgroupdesc_sms" msgid="4656988620100940350">"sende og se sms-beskeder"</string>
+ <string name="permgrouplab_storage" msgid="1971118770546336966">"Lagerplads"</string>
+ <string name="permgroupdesc_storage" msgid="637758554581589203">"få adgang til billeder, medier og filer på din enhed"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"optage lyd"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"tage billeder og optage video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"foretage og administrere telefonopkald"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorer"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"Få adgang til oplysninger om dine livstegn og din fysiske aktivitet"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Kropssensorer"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"få adgang til sensordata om dine livstegn"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"hente indholdet i vinduet"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"undersøge indholdet i et vindue, du interagerer med."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"aktivere Udforsk ved berøring"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Tillader, at appen kan modtage og behandle mms-beskeder. Det betyder, at appen kan overvåge eller slette de beskeder, der sendes til din enhed, uden at vise dem til dig."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"læse Cell Broadcast-beskeder"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Tillader, at appen læser Cell Broadcast-beskeder, der modtages af din enhed. I nogle områder sendes der Cell Broadcast-beskeder for at advare om nødsituationer. Ondsindede apps kan forstyrre ydelsen eller driften af ​din ​enhed, når der modtages en Cell Broadcast-besked om en nødsituation."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Dine konti"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Få adgang til de tilgængelige konti."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"læse feeds, jeg abonnerer på"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Tillader, at appen kan hente oplysninger om de feeds, der synkroniseres."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"Send og se sms-beskeder"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 121e426..ba8580f 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"Bilder und Videos aufzunehmen"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"Telefonanrufe zu tätigen und zu verwalten"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensoren"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"Auf Informationen zu Ihren Vitaldaten und physischen Aktivitäten zugreifen"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Körpersensoren"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"Auf Sensordaten zu Ihren Vitaldaten zugreifen"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Fensterinhalte abrufen"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Die Inhalte eines Fensters mit dem Sie interagieren werden abgerufen."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"\"Tippen &amp; Entdecken\" aktivieren"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Ermöglicht der App, MMS zu empfangen und zu verarbeiten. Das bedeutet, dass die App an Ihr Gerät gesendete Nachrichten überwachen und löschen kann, ohne sie Ihnen anzuzeigen."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"Cell Broadcast-Nachrichten lesen"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Ermöglicht der App, von Ihrem Gerät empfangene Cell Broadcast-Nachrichten zu lesen. Cell Broadcast-Benachrichtigungen werden an einigen Standorten gesendet, um Sie über Notfallsituationen zu informieren. Schädliche Apps können die Leistung oder den Betrieb Ihres Geräts beeinträchtigen, wenn eine Cell Broadcast-Notfallbenachrichtigung eingeht."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Ihre Konten"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Zugriff auf verfügbare Konten"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"Abonnierte Feeds lesen"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Ermöglicht der App, Details zu den zurzeit synchronisierten Feeds abzurufen"</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS senden und abrufen"</string>
@@ -600,7 +598,7 @@
<string name="emailTypeMobile" msgid="119919005321166205">"Mobil"</string>
<string name="postalTypeCustom" msgid="8903206903060479902">"Benutzerdefiniert"</string>
<string name="postalTypeHome" msgid="8165756977184483097">"Privat"</string>
- <string name="postalTypeWork" msgid="5268172772387694495">"Büro"</string>
+ <string name="postalTypeWork" msgid="5268172772387694495">"Geschäftlich"</string>
<string name="postalTypeOther" msgid="2726111966623584341">"Sonstige"</string>
<string name="imTypeCustom" msgid="2074028755527826046">"Benutzerdefiniert"</string>
<string name="imTypeHome" msgid="6241181032954263892">"Privat"</string>
@@ -1061,7 +1059,7 @@
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> wird vorbereitet"</string>
<string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Nach Fehlern wird gesucht"</string>
<string name="ext_media_new_notification_message" msgid="7589986898808506239">"Neue <xliff:g id="NAME">%s</xliff:g> entdeckt"</string>
- <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Für die Übertragung von Fotos und Medien"</string>
+ <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Zum Übertragen von Fotos und Medien"</string>
<string name="ext_media_unmountable_notification_title" msgid="8295123366236989588">"<xliff:g id="NAME">%s</xliff:g> beschädigt"</string>
<string name="ext_media_unmountable_notification_message" msgid="1586311304430052169">"<xliff:g id="NAME">%s</xliff:g> ist beschädigt. Zum Reparieren tippen."</string>
<string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"<xliff:g id="NAME">%s</xliff:g> nicht unterstützt"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 9c9db11..fe6548f 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"λήψη φωτογραφιών και εγγραφή βίντεο"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Τηλέφωνο"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"πραγματοποίηση και διαχείριση τηλεφωνικών κλήσεων"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Αισθητήρες"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"πρόσβαση σε πληροφορίες σχετικά με τις ζωτικές ενδείξεις και τη σωματική δραστηριότητα"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Αισθητήρες σώματος"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"πρόσβαση στα δεδομένα αισθητήρα σχετικά με τις ζωτικές ενδείξεις σας"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Ανάκτηση του περιεχομένου του παραθύρου"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Έλεγχος του περιεχομένου ενός παραθύρου με το οποίο αλληλεπιδράτε."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ενεργοποίηση της \"Εξερεύνησης με άγγιγμα\""</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Επιτρέπει στην εφαρμογή τη λήψη και την επεξεργασία μηνυμάτων MMS. Αυτό σημαίνει ότι η εφαρμογή θα μπορούσε να παρακολουθήσει ή να διαγράψει τα μηνύματα που αποστέλλονται στη συσκευή σας χωρίς αυτά να εμφανιστούν σε εσάς."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ανάγνωση μηνυμάτων που έχουν μεταδοθεί μέσω κινητού τηλεφώνου"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Επιτρέπει στην εφαρμογή την ανάγνωση μηνυμάτων που έχουν μεταδοθεί μέσω κινητού τηλεφώνου και έχουν ληφθεί από τη συσκευή σας. Ειδοποιήσεις που μεταδίδονται μέσω κινητού παραδίδονται σε ορισμένες τοποθεσίες για να σας προειδοποιήσουν για καταστάσεις έκτακτης ανάγκης. Κακόβουλες εφαρμογές ενδέχεται να παρεμποδίσουν την απόδοση ή τη λειτουργία της συσκευής σας κατά τη λήψη μετάδοσης μέσω κινητού σχετικά με μια επείγουσα κατάσταση."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Οι λογαριασμοί σας"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Πρόσβαση στους διαθέσιμους λογαριασμούς."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ανάγνωση ροών δεδομένων στις οποίες έχετε εγγραφεί"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Επιτρέπει στην εφαρμογή τη λήψη λεπτομερειών σχετικά με τις τρέχουσες συγχρονισμένες ροές δεδομένων."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"αποστολή και προβολή μηνυμάτων SMS"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index f2f378c..5cc4688 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"take pictures and record video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telephone"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"make and manage phone calls"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensors"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"access information about your vital signs and physical activity"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Body Sensors"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"access sensor data about your vital signs"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Retrieve window content"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspect the content of a window that you\'re interacting with."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Turn on Explore by Touch"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Allows the app to receive and process MMS messages. This means that the app could monitor or delete messages sent to your device without showing them to you."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"read mobile broadcast messages"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Allows the app to read mobile broadcast messages received by your device. Cell broadcast alerts are delivered in some locations to warn you of emergency situations. Malicious apps may interfere with the performance or operation of your device when an emergency mobile broadcast is received."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Your accounts"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Access the available accounts."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"read subscribed feeds"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Allows the app to get details about the currently synced feeds."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"send and view SMS messages"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index f2f378c..5cc4688 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"take pictures and record video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telephone"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"make and manage phone calls"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensors"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"access information about your vital signs and physical activity"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Body Sensors"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"access sensor data about your vital signs"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Retrieve window content"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspect the content of a window that you\'re interacting with."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Turn on Explore by Touch"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Allows the app to receive and process MMS messages. This means that the app could monitor or delete messages sent to your device without showing them to you."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"read mobile broadcast messages"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Allows the app to read mobile broadcast messages received by your device. Cell broadcast alerts are delivered in some locations to warn you of emergency situations. Malicious apps may interfere with the performance or operation of your device when an emergency mobile broadcast is received."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Your accounts"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Access the available accounts."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"read subscribed feeds"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Allows the app to get details about the currently synced feeds."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"send and view SMS messages"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index f2f378c..5cc4688 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"take pictures and record video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telephone"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"make and manage phone calls"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensors"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"access information about your vital signs and physical activity"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Body Sensors"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"access sensor data about your vital signs"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Retrieve window content"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspect the content of a window that you\'re interacting with."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Turn on Explore by Touch"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Allows the app to receive and process MMS messages. This means that the app could monitor or delete messages sent to your device without showing them to you."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"read mobile broadcast messages"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Allows the app to read mobile broadcast messages received by your device. Cell broadcast alerts are delivered in some locations to warn you of emergency situations. Malicious apps may interfere with the performance or operation of your device when an emergency mobile broadcast is received."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Your accounts"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Access the available accounts."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"read subscribed feeds"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Allows the app to get details about the currently synced feeds."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"send and view SMS messages"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 8b4f4b7..6c9f722 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"tomar fotografías y grabar videos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Teléfono"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"realizar y administrar llamadas telefónicas"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensores"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"acceder a información acerca de tus signos vitales y la actividad física"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensores corporales"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"acceder a los datos del sensor acerca de tus signos vitales"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar el contenido de las ventanas"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona el contenido de la ventana con la que estés interactuando."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar la Exploración táctil"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permite que la aplicación reciba y procese mensajes MMS, lo que significa que podría controlar o eliminar mensajes enviados al dispositivo sin mostrártelos."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"Leer mensajes de difusión móvil"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite a la aplicación leer los mensajes de difusión móvil que recibe tu dispositivo. En algunas ubicaciones, las alertas de difusión móvil se envían para informar situaciones de emergencia. Las aplicaciones maliciosas pueden afectar el rendimiento o funcionamiento de tu dispositivo cuando se recibe un un mensaje de difusión móvil de emergencia."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Tus cuentas"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Acceder a las cuentas disponibles."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"leer canales suscritos"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permite que la aplicación obtenga detalles sobre los feeds sincronizados en este momento."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"enviar y ver mensajes SMS"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 53e3e20..f62b5c5 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"hacer fotos y grabar vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Teléfono"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"hacer y administrar llamadas de teléfono"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensores"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"acceder a información sobre tus constantes vitales y tu actividad física"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensores corporales"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"acceder a datos del sensor sobre tus constantes vitales"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar el contenido de la ventana"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona el contenido de una ventana con la que estés interactuando."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar la exploración táctil"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permite que la aplicación reciba y procese mensajes MMS, lo que significa que podría utilizar este permiso para controlar o eliminar mensajes enviados al dispositivo sin mostrárselos al usuario."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"leer mensajes de difusión móvil"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite que la aplicación lea mensajes de difusión móvil que haya recibido el dispositivo. Las alertas de difusión móvil se envían en algunas ubicaciones para avisar de situaciones de emergencia. Es posible que las aplicaciones malintencionadas interfieran en el rendimiento o en el funcionamiento del dispositivo si se recibe una alerta de difusión móvil de emergencia."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Tus cuentas"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Acceder a las cuentas disponibles"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"leer feeds a los que está suscrito el usuario"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permite que la aplicación obtenga detalles sobre los feeds sincronizados actualmente."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"enviar y ver mensajes SMS"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index a9d9db5..9b2b281 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"pildistamine ja video salvestamine"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"helistamine ja telefonikõnede haldamine"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Andurid"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"juurde pääseda teabele eluliste näitajate ja füüsiliste tegevuste kohta"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Kehaandurid"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"juurdepääs anduri andmetele teie eluliste näitajate kohta"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Akna sisu toomine"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Tutvuge kasutatava akna sisuga."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Puudutusega sirvimise sisselülitamine"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Võimaldab rakendusel vastu võtta ja töödelda multimeediumsõnumeid. See tähendab, et rakendus võib jälgida või kustutada teie seadmele saadetud sõnumeid neid teile näitamata."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"mobiilsidesõnumite lugemine"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Võimaldab rakendusel lugeda seadme vastu võetud mobiilsidesõnumeid. Mobiilsidemärguandeid edastatakse mõnes asukohas eriolukorrast teavitamiseks. Pahatahtlikud rakendused võivad segada seadme toimivust või tööd eriolukorra sõnumi vastuvõtmisel."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Teie kontod"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Juurdepääs saadaolevatele kontodele."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"loe tellitud kanaleid"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Võimaldab rakendusel saada üksikasju praegu sünkroonitavate voogude kohta."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"saata ja vaadata SMS-sõnumeid"</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index 3c73f4f..99f48ad 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"Atera argazkiak eta grabatu bideoak"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefonoa"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"Egin eta kudeatu telefono-deiak"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sentsoreak"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"Atzitu zure bizi-konstanteei eta ariketa fisikoari buruzko informazioa"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Gorputz-sentsoreak"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"Atzitu bizi-konstanteei buruzko sentsore-datuak"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Eskuratu leihoko edukia"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Arakatu irekita daukazun leihoko edukia."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktibatu ukipen bidez arakatzeko eginbidea"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMS mezuak jasotzeko eta prozesatzeko baimena ematen die aplikazioei. Horrela, aplikazioak gailura bidalitako mezuak kontrola eta ezaba ditzake zuri erakutsi gabe."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"sare mugikor bidezko igorpen-mezuak irakurtzea"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Gailuak jasotako sare mugikor bidezko igorpenen mezuak irakurtzeko baimena ematen die aplikazioei. Sare mugikor bidezko igorpen-alertak kokapen batzuetan ematen dira larrialdi-egoeren berri emateko. Aplikazio gaiztoek gailuaren errendimendua edo funtzionamendua oztopa dezakete larrialdi-igorpen horietako bat jasotzen denean."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Zure kontuak"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Sartu kontu erabilgarrietan."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"irakurri harpidetutako jarioak"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Unean sinkronizatutako jarioei buruzko xehetasunak lortzea baimentzen die aplikazioei."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"bidali eta ikusi SMS mezuak"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index dfcabc3..c804f40 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"عکس گرفتن و فیلم‌برداری"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"تلفن"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"برقراری و مدیریت تماس‌های تلفنی"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"حسگرها"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"دسترسی به اطلاعات مربوط به علائم حیاتی و فعالیت فیزیکی شما"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"حسگرهای بدن"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"دسترسی به داده‌های حسگر در رابطه با علائم حیاتی شما"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"محتوای پنجره را بازیابی کند"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"محتوای پنجره‌ای را که درحال تعامل با آن هستید بررسی می‌کند."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"فعال‌سازی کاوش لمسی"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"‏به برنامه اجازه می‌دهد پیام‌های MMS را دریافت و پردازش کند. این یعنی برنامه می‌تواند پیام‌های ارسالی به دستگاه شما را بدون نمایش آن‌ها به شما حذف یا کنترل کند."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"خواندن پیام‌های پخش سلولی"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"‏به برنامه اجازه می‎دهد پیام‌های پخش سلولی دستگاه شما را بخواند. هشدارهای پخش سلولی در برخی از موقعیت‌های مکانی تحویل داده می‎شوند تا موقعیت‌های اضطراری را به شما اعلام کنند. وقتی پخش سلولی دریافت می‎شود، ممکن است برنامه‎های مخرب در عملکرد یا کارکرد دستگاه شما اختلال ایجاد کنند."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"حساب‌های شما"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"به حساب‌های موجود دسترسی داشته باشید."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"خواندن فیدهای مشترک"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"‏به برنامه اجازه می‎دهد تا جزئیات مربوط به فیدهای همگام شده کنونی را دریافت کند."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"ارسال و نمایش پیام‌های پیامک"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 76d6fab..8ae5092 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ottaa kuvia ja videoita"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Puhelin"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"soittaa ja hallinnoida puheluita"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Anturit"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"käyttää tietoja kehostasi ja liikuntaharjoituksistasi"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Kehon anturit"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"käyttää anturitietoja elintoiminnoistasi"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Noutaa ikkunan sisältöä"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Tarkistaa käyttämäsi ikkunan sisältö."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ottaa kosketuksella tutkiminen käyttöön"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Antaa sovelluksen vastaanottaa ja käsitellä multimediaviestejä. Sovellus voi valvoa tai poistaa laitteeseesi lähetettyjä viestejä näyttämättä niitä sinulle."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lue tiedotteita"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Antaa sovelluksen lukea laitteesi vastaanottamia tiedotteita. Tiedotteiden avulla ilmoitetaan hätätilanteista joissakin paikoissa. Haitalliset sovellukset voivat häiritä laitteen toimintaa laitteen vastaanottaessa hätätiedotteen."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Omat tilit"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Käytä saatavilla olevia tilejä."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lukea tilattuja syötteitä"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Antaa sovelluksen saada tietoja tällä hetkellä synkronoitavista syötteistä."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"lähettää ja tarkastella tekstiviestejä"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 646ab21..6296f78 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"prendre des photos et filmer des vidéos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Téléphone"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"faire et gérer des appels téléphoniques"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Capteurs"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"accéder à de l\'information relative à vos signes vitaux et à votre activité physique"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Capteurs corporels"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accéder aux données des capteurs sur vos signes vitaux"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Récupérer le contenu d\'une fenêtre"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecter le contenu d\'une fenêtre avec laquelle vous interagissez."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activer la fonctionnalité Explorer au toucher"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permet à l\'application de recevoir et de traiter les messages multimédias. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lire les messages de diffusion cellulaire"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permet à l\'application de lire les messages de diffusion cellulaire que votre appareil reçoit. Dans certaines zones géographiques, des alertes vous sont envoyées afin de vous prévenir en cas de situation d\'urgence. Des applications malveillantes peuvent venir perturber les performances ou le fonctionnement de votre appareil lors de la réception d\'un message de diffusion cellulaire."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Vos comptes"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Accéder aux comptes disponibles"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lire les flux auxquels vous êtes abonné"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permet à l\'application d\'obtenir des données sur les flux en cours de synchronisation."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"envoyer et afficher des messages texte"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index c235486..8cb6dc1 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"prendre des photos et enregistrer des vidéos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Téléphone"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"effectuer et gérer des appels téléphoniques"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Capteurs"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"accéder à des informations relatives à vos signes vitaux et à votre activité physique"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Capteurs corporels"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accéder aux données des capteurs relatives à vos signes vitaux"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Récupérer le contenu d\'une fenêtre"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecter le contenu d\'une fenêtre avec laquelle vous interagissez"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activer la fonctionnalité Explorer au toucher"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permet à l\'application de recevoir et de traiter les MMS. Cette autorisation lui donne la possibilité de surveiller ou supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lire les messages reçus via un canal de diffusion cellulaire"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permet à l\'application de lire les messages que votre appareil reçoit via un canal de diffusion cellulaire. Dans certaines zones géographiques, des alertes vous sont envoyées afin de vous prévenir en cas de situation d\'urgence. Les applications malveillantes peuvent venir perturber les performances ou le fonctionnement de votre appareil lorsqu\'un message est reçu via un canal de diffusion cellulaire."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Vos comptes"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Accéder aux comptes disponibles"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lire les flux auxquels vous êtes abonné"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permet à l\'application d\'obtenir des informations sur les flux en cours de synchronisation."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"envoyer et consulter des SMS"</string>
@@ -310,7 +308,7 @@
<string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Permet à l\'application d\'envoyer des intentions de diffusion \"persistantes\", qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir la tablette ou la rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
<string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Permet à l\'application d\'envoyer des diffusions ancrées, qui persistent au terme de la diffusion. L\'utilisation excessive de cette fonctionnalité, qui nécessite beaucoup de mémoire, peut ralentir le téléviseur ou nuire à sa stabilité."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Permet à l\'application d\'envoyer des intentions de diffusion \"persistantes\", qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir le téléphone ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
- <string name="permlab_readContacts" msgid="8348481131899886131">"voir les contacts"</string>
+ <string name="permlab_readContacts" msgid="8348481131899886131">"Voir les contacts"</string>
<string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre tablette, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des e-mails ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
<string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Permet à l\'application de lire les données relatives à vos contacts sur le téléviseur, y compris la fréquence de vos appels, de vos e-mails et de toute autre communication avec ces personnes. Cette autorisation permet aux applications d\'enregistrer les données relatives à vos contacts. Les applications malveillantes sont susceptibles de partager ces données à votre insu."</string>
<string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre téléphone, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des e-mails ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
@@ -356,7 +354,7 @@
<string name="permdesc_flashlight" msgid="6522284794568368310">"Permet à l\'application de contrôler la lampe de poche."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"appeler directement les numéros de téléphone"</string>
<string name="permdesc_callPhone" msgid="3740797576113760827">"Permet à l\'application d\'appeler des numéros de téléphone sans votre intervention. Cette autorisation peut entraîner des frais ou des appels imprévus et ne permet pas à l\'application d\'appeler des numéros d\'urgence. Les applications malveillantes peuvent générer des frais en passant des appels sans votre consentement."</string>
- <string name="permlab_readPhoneState" msgid="9178228524507610486">"voir l\'état et l\'identité du téléphone"</string>
+ <string name="permlab_readPhoneState" msgid="9178228524507610486">"Voir l\'état et l\'identité du téléphone"</string>
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permet à l\'application d\'accéder aux fonctionnalités téléphoniques de l\'appareil. Cette autorisation permet à l\'application de déterminer le numéro de téléphone et les identifiants de l\'appareil, si un appel est actif et le numéro distant connecté par un appel."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"empêcher la tablette de passer en mode veille"</string>
<string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"empêcher l\'activation du mode veille sur le téléviseur"</string>
@@ -412,7 +410,7 @@
<string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Permet à l\'application d\'accéder à la configuration du Bluetooth sur le téléphone, et d\'établir et accepter des connexions avec les appareils associés."</string>
<string name="permlab_nfc" msgid="4423351274757876953">"contrôler la communication en champ proche"</string>
<string name="permdesc_nfc" msgid="7120611819401789907">"Permet à l\'application de communiquer avec des tags, des cartes et des lecteurs compatibles avec la technologie NFC (communication en champ proche)."</string>
- <string name="permlab_disableKeyguard" msgid="3598496301486439258">"désactiver le verrouillage de l\'écran"</string>
+ <string name="permlab_disableKeyguard" msgid="3598496301486439258">"Désactiver le verrouillage de l\'écran"</string>
<string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permet à l\'application de désactiver le verrouillage des touches et toute mesure de sécurité via mot de passe associée. Par exemple, votre téléphone désactive le verrouillage des touches lorsque vous recevez un appel, puis le réactive lorsque vous raccrochez."</string>
<string name="permlab_manageFingerprint" msgid="5640858826254575638">"Gérer le matériel d\'empreintes digitales"</string>
<string name="permdesc_manageFingerprint" msgid="178208705828055464">"Autoriser l\'application à invoquer des méthodes pour ajouter et supprimer des modèles d\'empreintes digitales"</string>
@@ -440,11 +438,11 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Permet à une application de modifier les paramètres de synchronisation d\'un compte. Cette autorisation peut, par exemple, être utilisée pour activer la synchronisation de l\'application Contacts avec un compte."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"Lecture des statistiques de synchronisation"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Permet à une application d\'accéder aux statistiques de synchronisation d\'un compte, y compris l\'historique des événements de synchronisation et le volume de données synchronisées."</string>
- <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"voir le contenu de la mémoire USB"</string>
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"Voir le contenu de la mémoire USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"voir le contenu de la carte SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Permettre de lire contenu de la mémoire de stockage USB"</string>
<string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Permettre à l\'application de lire le contenu de la carte SD"</string>
- <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modifier ou supprimer le contenu de la mémoire USB"</string>
+ <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"Modifier ou supprimer le contenu de la mémoire USB"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modifier ou supprimer le contenu de la carte SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Permet à l\'application de modifier le contenu de la mémoire de stockage USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permet à l\'application de modifier le contenu de la carte SD."</string>
@@ -1014,7 +1012,7 @@
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"NOUVEAU"</font>" :"</string>
<string name="perms_description_app" msgid="5139836143293299417">"Fourni par <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="no_permissions" msgid="7283357728219338112">"Aucune autorisation requise"</string>
- <string name="perm_costs_money" msgid="4902470324142151116">"cela peut engendrer des frais"</string>
+ <string name="perm_costs_money" msgid="4902470324142151116">"Cela peut engendrer des frais"</string>
<string name="usb_storage_activity_title" msgid="4465055157209648641">"Mémoire de stockage de masse USB"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"Connecté par USB"</string>
<string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Vous êtes connecté à votre ordinateur via un câble USB. Appuyez sur le bouton ci-dessous pour copier des fichiers de votre ordinateur vers la mémoire de stockage USB de votre appareil Android, ou inversement."</string>
@@ -1337,7 +1335,7 @@
<string name="accessibility_enabled" msgid="1381972048564547685">"L\'accessibilité a bien été activée."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilité annulée."</string>
<string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="user_switching_message" msgid="2871009331809089783">"Passage à (<xliff:g id="NAME">%1$s</xliff:g>) en cours…"</string>
+ <string name="user_switching_message" msgid="2871009331809089783">"Chargement du profil de <xliff:g id="NAME">%1$s</xliff:g>..."</string>
<string name="owner_name" msgid="2716755460376028154">"Propriétaire"</string>
<string name="error_message_title" msgid="4510373083082500195">"Erreur"</string>
<string name="error_message_change_not_allowed" msgid="1347282344200417578">"Votre administrateur n\'autorise pas cette modification."</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 001ea06..bd6b4f4 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"tirar fotos e gravar vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Teléfono"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"facer e xestionar chamadas telefónicas"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensores"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"accede a información sobre as túas constantes vitais e a actividade física"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensores corporais"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accede aos datos do sensor sobre as túas constantes vitais"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar contido da ventá"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona o contido dunha ventá coa que estás interactuando."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar a exploración táctil"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permite á aplicación recibir e procesar mensaxes MMS. Isto significa que a aplicación pode supervisar ou eliminar mensaxes enviadas ao teu dispositivo sen mostrarchas."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ler mensaxes de difusión móbil"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite á aplicación ler mensaxes de difusión móbil recibidas polo teu dispositivo. As alertas de difusión móbil entréganse nalgunhas situacións para avisar de situacións de emerxencia. É posible que aplicacións maliciosas afecten ao rendemento ou funcionamento do teu dispositivo cando se recibe unha difusión móbil de emerxencia."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"As túas contas"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Acceder ás contas dispoñibles."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ler feeds subscritos"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permite á aplicación obter detalles acerca dos feeds sincronizados actualmente."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"enviar e consultar mensaxes de SMS"</string>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index 44ea388..2c4bcd7 100644
--- a/core/res/res/values-gu-rIN/strings.xml
+++ b/core/res/res/values-gu-rIN/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ચિત્રો લો અને વિડિઓ રેકોર્ડ કરો"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ફોન"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ફોન કૉલ કરો તથા સંચાલિત કરો"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"સેન્સર્સ"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"તમારા મહત્વપૂર્ણ ચિહ્નો અને શારીરિક પ્રવૃત્તિ વિશેની માહિતી ઍક્સેસ કરો"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"બોડી સેન્સર્સ"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"તમારા મહત્વપૂર્ણ ચિહ્નો વિશે સેન્સર ડેટા ઍક્સેસ કરો"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"વિંડો સામગ્રી પુનર્પ્રાપ્ત કરો"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"તમે જેની સાથે ક્રિયાપ્રતિક્રિયા કરી રહ્યાં છો તે વિંડોની સામગ્રીની તપાસ કરો."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ટચ કરીને અન્વેષણ કરો સક્ષમ કરો"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"એપ્લિકેશનને MMS સંદેશા પ્રાપ્ત કરવાની અને તેના પર પ્રક્રિયા કરવાની મંજૂરી આપે છે. આનો અર્થ એ કે એપ્લિકેશન તમને દર્શાવ્યા વિના તમારા ઉપકરણ પર મોકલેલ સંદેશાઓનું નિરીક્ષણ કરી શકે છે અથવા કાઢી નાખી શકે છે."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"સેલ બ્રોડકાસ્ટ સંદેશા વાંચો"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"એપ્લિકેશનને તમારા ઉપકરણ દ્વારા પ્રાપ્ત થયેલ સેલ બ્રોડકાસ્ટ સંદેશાને વાંચવાની મંજૂરી આપે છે. સેલ બ્રોડકાસ્ટ ચેતવણીઓ તમને કટોકટીની સ્થિતિઓ અંગે ચેતવવા માટે કેટલાક સ્થાનોમાં વિતરિત થાય છે. જ્યારે કટોકટીનો સેલ બ્રોડકાસ્ટ પ્રાપ્ત થાય ત્યારે દુર્ભાવનાપૂર્ણ એપ્લિકેશન્સ તમારા ઉપકરણના પ્રદર્શન અથવા ઓપરેશનમાં હસ્તક્ષેપ કરી શકે છે."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"તમારા એકાઉન્ટ્સ"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ઉપલબ્ધ એકાઉન્ટ્સ ઍક્સેસ કરો."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"સબ્સ્ક્રાઇબ કરેલ ફીડ્સ વાંચો"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"એપ્લિકેશનને હાલમાં સમન્વયિત ફીડ્સ વિશે વિગતો મેળવવાની મંજૂરી આપે છે."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS સંદેશા મોકલો અને જુઓ"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index a9daf0b..3d4ea0a 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"चित्र लें और वीडियो रिकॉर्ड करें"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"फ़ोन"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"फ़ोन कॉल करें और प्रबंधित करें"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"संवेदक"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"अपने महत्वपूर्ण संकेतों और शारीरिक गतिविधि के बारे में जानकारी ऐक्सेस करें"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"शरीर संवेदक"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"अपने महत्वपूर्ण संकेतों के बारे में सेंसर डेटा को ऐक्सेस करें"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"विंडो सामग्री प्राप्त करें"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"उस विंडो की सामग्री का निरीक्षण करें जिससे आप सहभागिता कर रहे हैं."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"स्पर्श द्वारा एक्सप्लोर करें को चालू करें"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"ऐप्स को MMS संदेशों को प्राप्‍त और संसाधित करने देता है. इसका अर्थ है कि ऐप्स आपके डिवाइस पर भेजे गए संदेशों की निगरानी आपको दिखाए बिना कर सकता है और उन्‍हें हटा सकता है."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"सेल प्रसारण संदेश पढ़ें"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ऐप्स को आपके डिवाइस द्वारा प्राप्त सेल प्रसारण संदेशों को पढ़ने देता है. कुछ स्‍थानों पर आपको आपातकालीन स्‍थितियों की चेतावनी देने के लिए सेल प्रसारण अलर्ट वितरित किए जाते हैं. आपातकालीन सेल प्रसारण प्राप्त होने पर दुर्भावनापूर्ण ऐप्स आपके डिवाइस के निष्‍पादन या संचालन में हस्‍तक्षेप कर सकते हैं."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"आपके खाते"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"उपलब्‍ध खातों में पहुंचें."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"सदस्यता-प्राप्त फ़ीड पढ़ें"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ऐप्स को वर्तमान में समन्वयित फ़ीड के बारे में विवरण प्राप्त करने देता है."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS संदेश भेजें और देखें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 3d02071..6e77186 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -243,8 +243,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"snimati fotografije i videozapise"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"uspostavljati telefonske pozive i upravljati njima"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Senzori"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"pristupiti informacijama o vašim vitalnim znakovima i fizičkoj aktivnosti"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Biometrijski senzori"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"pristupiti podacima senzora o vašim vitalnim znakovima"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Dohvaćati sadržaj prozora"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Istražite sadržaj prozora koji upotrebljavate."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Uključiti značajku Istraži dodirom"</string>
@@ -271,8 +271,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Aplikaciji omogućuje primanje i obradu MMS poruka. To znači da aplikacija može nadzirati ili izbrisati poruke poslane na vaš uređaj, a da vam ih ne prikaže."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"čitaj poruke koje se emitiraju unutar mobilne mreže"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Omogućuje aplikaciji čitanje poruka emitiranih unutar mobilne mreže koje prima vaš uređaj. Upozorenja koja se emitiraju na području mobilne mreže dostavljaju se na nekim lokacijama kako bi upozorila korisnike na hitne situacije. Zlonamjerne aplikacije mogu ometati izvršavanje ili rad vašeg uređaja kada stigne hitno upozorenje koje se emitira unutar mobilne mreže."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Vaši računi"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Pristup dostupnim računima."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"čitanje pretplaćenih feedova"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Aplikaciji omogućuje dohvaćanje detalja o trenutačno sinkroniziranim feedovima."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"slati i pregledavati SMS poruke"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 54e6e56..ad08b75 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"fotók és videók készítése"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"telefonhívások kezdeményezése és kezelése"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Érzékelők"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"életjelekkel és fizikai tevékenységgel kapcsolatos információk elérése"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Testérzékelők"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"az érzékelők által mért, életjelekkel kapcsolatos adatok elérése"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Ablaktartalom lekérdezése"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"A használt ablak tartalmának vizsgálata."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Felfedezés érintéssel bekapcsolása"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Lehetővé teszi az alkalmazás számára, hogy MMS-eket fogadjon és dolgozzon fel. Ez azt jelenti, hogy az alkalmazás megfigyelheti vagy törölheti a beérkező üzeneteket anélkül, hogy Ön látná azokat."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"cellán belüli üzenetek olvasása"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Lehetővé teszi az alkalmazás számára az eszközre érkező cellán belüli üzenetek olvasását. Bizonyos helyeken figyelmeztető üzeneteket kaphat a cellán belül a vészhelyzetekről. A rosszindulatú alkalmazások befolyásolhatják az eszköz teljesítményét vagy működését vészhelyzeti cellaüzenet érkezésekor."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Az Ön fiókjai"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Hozzáférés az elérhető fiókokhoz."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"feliratkozott hírcsatornák olvasása"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Lehetővé teszi az alkalmazás számára, hogy részleteket kapjon a jelenleg szinkronizált hírcsatornákról."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS-ek küldése és megtekintése"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index b8dc2de..8ddc6d9 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"լուսանկարում և տեսագրում"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Հեռախոս"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"հեռախոսազանգերի կատարում և կառավարում"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Սենսորներ"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"օգտագործել ձեր հիմնական ֆիզիոլոգիական ցուցանիշների և ֆիզիկական գործունեության վերաբերյալ տեղեկությունները"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Մարմնի սենսորներ"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"օգտագործել ձեր հիմնական ֆիզիոլոգիական ցուցանիշների վերաբերյալ սենսորի տվյալները"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Առբերել պատուհանի բովանդակությունը"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Ստուգեք պատուհանի բովանդակությունը, որի հետ փոխգործակցում եք:"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Միացնել Հպման միջոցով հետազոտումը"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Թույլ է տալիս հավելվածին ստանալ և մշակել MMS հաղորդագրությունները: Սա նշանակում է, որ հավելվածը կարող է ստուգել կամ ջնջել ձեր սարքին ուղարկված հաղորդագրությունները` առանց դրանք ձեզ ցուցադրելու:"</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"կարդալ բջջային զեկուցվող հաղորդագրությունները"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Թույլ է տալիս հավելվածին կարդալ ձեր սարքի կողմից ստացված բջջային հեռարձակվող հաղորդագրությունները: Բջջային հեռարձակվող զգուշացումները ուղարկվում են որոշ վայրերում` արտակարգ իրավիճակների մասին ձեզ զգուշացնելու համար: Վնասարար հավելվածները կարող են խանգարել ձեր սարքի արդյունավետությանը կամ շահագործմանը, երբ ստացվում է արտակարգ իրավիճակի մասին բջջային հաղորդում:"</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Ձեր հաշիվները"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Մուտքի հնարավորություն առկա հաշիվներ:"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"կարդալ բաժանորդագրված հոսքերը"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Թույլ է տալիս հավելվածին մանրամասներ ստանալ ընթացիկ համաժամեցված հոսքերի մասին:"</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS հաղորդագրությունների ուղարկում և ընթերցում"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 305e318..cc4334c 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"mengambil gambar dan merekam video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telepon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"melakukan dan mengelola panggilan telepon"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensor"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"mengakses informasi tentang tanda-tanda vital dan aktivitas fisik"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensor Tubuh"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"mengakses data sensor tentang tanda-tanda vital"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Mengambil konten jendela"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Memeriksa konten jendela tempat Anda berinteraksi."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Mengaktifkan Jelajahi dengan Sentuhan"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Memungkinkan aplikasi menerima dan memproses pesan MMS. Ini artinya aplikasi dapat memantau atau menghapus pesan yang dikirim ke perangkat Anda tanpa menunjukkannya kepada Anda."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"membaca pesan siaran seluler"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Mengizinkan aplikasi membaca pesan siaran seluler yang diterima perangkat Anda. Lansiran siaran seluler dikirimkan di beberapa lokasi untuk memperingatkan Anda tentang situasi darurat. Aplikasi berbahaya dapat mengganggu kinerja atau operasi perangkat Anda saat siaran seluler darurat diterima."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Akun-akun Anda"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Akses akun yang tersedia."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"baca umpan langganan"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Mengizinkan apl mendapatkan detail tentang umpan yang saat ini sedang disinkronkan."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"mengirim dan melihat pesan SMS"</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index fa24444..9eabd82 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"taka myndir og taka upp myndskeið"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Sími"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"hringja og stjórna símtölum"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Skynjarar"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"fá aðgang að upplýsingum um líkamsstarfsemi þína og hreyfingu"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Líkamsskynjarar"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"aðgangur að skynjaragögnum yfir lífsmörk þín"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Sækja innihald glugga"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Kanna innihald glugga sem þú ert að nota."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Kveikja á snertikönnun"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Leyfir forriti að taka á móti og vinna úr MMS-skilaboðum. Þetta þýðir að forritið getur fylgst með eða eytt skilaboðum sem send eru í tækið án þess að birta þér þau."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lesa skilaboð frá endurvarpa"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Leyfir forriti að lesa skilaboð frá endurvarpa sem tækið móttekur. Viðvaranir frá endurvarpa berast á tilteknum stöðum til að vara þig við neyðarástandi. Spilliforrit geta truflað afköst eða virkni tækisins þegar neyðarboð berast frá endurvarpa."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Reikningarnir þínir"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Aðgangur að tiltækum reikningum."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lesa strauma í áskrift"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Leyfir forriti að fá upplýsingar um straumana sem samstilltir eru á hverjum tíma."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"senda og skoða SMS-skilaboð"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index a764c9f..c9c55fc 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"acquisizione di foto e registrazione di video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefono"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"esecuzione e gestione delle telefonate"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensori"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"accesso alle informazioni sui tuoi parametri vitali e sulla tua attività fisica"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensori per il corpo"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accesso ai dati dei sensori sui tuoi parametri vitali"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperare contenuti finestra"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Esaminare i contenuti di una finestra con cui interagisci."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Attivare Esplora al tocco"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Consente all\'applicazione di ricevere ed elaborare messaggi MMS. Significa che l\'applicazione potrebbe monitorare o eliminare i messaggi inviati al tuo dispositivo senza mostrarteli."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lettura di messaggi cell broadcast"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Consente all\'applicazione di leggere i messaggi cell broadcast ricevuti dal dispositivo. Gli avvisi cell broadcast vengono trasmessi in alcune località per avvertire di eventuali situazioni di emergenza. Le applicazioni dannose potrebbero interferire con il rendimento o con il funzionamento del dispositivo quando si riceve un messaggio cell broadcast di emergenza."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"I tuoi account"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Accedere agli account disponibili."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lettura feed sottoscritti"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Consente all\'applicazione di ottenere dettagli sui feed attualmente sincronizzati."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"invio e lettura di SMS"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index d045237..256522f 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -212,7 +212,7 @@
<string name="global_action_power_off" msgid="4471879440839879722">"כיבוי"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"דיווח על באג"</string>
<string name="bugreport_title" msgid="2667494803742548533">"שלח דיווח על באג"</string>
- <string name="bugreport_message" msgid="398447048750350456">"פעולה זו תאסוף מידע על מצב המכשיר הנוכחי שלך על מנת לשלוח אותו כהודעת אימייל. היא תימשך זמן קצר מרגע פתיחת דיווח הבאג ועד שיהיה ניתן לבצע שליחה. אנא המתן בסבלנות."</string>
+ <string name="bugreport_message" msgid="398447048750350456">"פעולה זו תאסוף מידע על מצב המכשיר הנוכחי שלך על מנת לשלוח אותו כהודעת אימייל. היא תימשך זמן קצר מרגע פתיחת דיווח הבאג ועד לשליחת ההודעה בפועל. אנא המתן בסבלנות."</string>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"מצב שקט"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"הקול כבוי"</string>
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"קול מופעל"</string>
@@ -244,8 +244,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"צילום תמונות והקלטת וידאו"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"טלפון"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"התקשרות וניהול של שיחות טלפון"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"חיישנים"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"גישה אל מידע על הסימנים החיוניים והפעילות הגופנית שלך"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"חיישני גוף"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"גישה אל נתוני חיישנים של הסימנים החיוניים שלך"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"אחזור תוכן של חלון"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"בדוק את התוכן של חלון שאיתו אתה מבצע אינטראקציה."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"הפעלה של \'גילוי באמצעות מגע\'"</string>
@@ -272,8 +272,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"‏מאפשר לאפליקציה לקבל ולעבד הודעות MMS. משמעות הדבר היא שהאפליקציה יכולה לעקוב אחר הודעות שנשלחו למכשיר או למחוק אותן מבלי להציג לך אותן."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"קריאת הודעות שידור סלולרי"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"מאפשר לאפליקציה לקרוא הודעות שידור סלולרי שהתקבלו במכשיר שלך. התראות שידור סלולרי נשלחות במקומות מסוימים על מנת להזהיר אותך מפני מצבי חירום. אפליקציות זדוניות עשויות להפריע לביצועים או לפעולה של המכשיר שלך כאשר מתקבל שידור חירום סלולרי."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"החשבונות שלך"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"גישה לכל החשבונות הזמינים."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"קרא עדכוני מנויים"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"מאפשר לאפליקציה לקבל פרטים על ההזנות הנוכחיות שמסונכרנות."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"‏שליחה והצגה של הודעות SMS"</string>
@@ -476,8 +474,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"הרשאה זו מאפשרת למשתמש לבצע איגוד לממשק הרמה העליונה של שירות מאזין להתראות. הרשאה זו אף פעם אינה נחוצה לאפליקציות רגילים."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"איגוד לשירות ספק תנאי"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"מאפשרת לבעלים לאגד לממשק ברמה העליונה של שירות ספק תנאי. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
- <string name="permlab_bindDreamService" msgid="4153646965978563462">"‏איגוד לשירות Dream"</string>
- <string name="permdesc_bindDreamService" msgid="7325825272223347863">"‏מאפשרת לבעלים לבצע איגוד לממשק הרמה העליונה של שירות Dream. הרשאה זו אף פעם אינה נחוצה לאפליקציות רגילות."</string>
+ <string name="permlab_bindDreamService" msgid="4153646965978563462">"איגוד לשירות ׳חלום בהקיץ׳"</string>
+ <string name="permdesc_bindDreamService" msgid="7325825272223347863">"מאפשרת לבעלים לבצע איגוד לממשק הרמה העליונה של שירות ׳חלום בהקיץ׳. הרשאה זו אף פעם אינה נחוצה לאפליקציות רגילות."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"הפעלה של אפליקציית תצורה שסופקה על ידי ספק"</string>
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ההרשאה הזו מאפשרת לבעלים להפעיל את אפליקציית התצורה שסופקה על ידי ספק. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"קליטת מעקב אחר תנאי רשת"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 69e558e..f3a10ba 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -229,7 +229,7 @@
<string name="permgrouplab_contacts" msgid="3657758145679177612">"連絡先"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"連絡先へのアクセス"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"位置情報"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"この端末の位置情報にアクセス"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"この端末の位置情報へのアクセス"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"カレンダー"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"カレンダーへのアクセス"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"写真の撮影と動画の記録"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"電話"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"通話の発信と管理"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"センサー"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"バイタルサインや身体活動に関する情報へのアクセス"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"ボディーセンサー"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"バイタルサインに関するセンサーデータへのアクセス"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ウィンドウコンテンツの取得"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ユーザーがアクセスしているウィンドウのコンテンツを検査します。"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"タッチガイドの有効化"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMSメッセージの受信と処理をアプリに許可します。これにより、アプリが端末に届いたメッセージを表示することなく監視または削除できるようになります。"</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"緊急警報SMSの読み取り"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"端末で受信した緊急警報SMSの読み取りをアプリに許可します。緊急警報は、緊急事態を警告する目的で一部の地域に配信されます。緊急警報の受信時に、悪意のあるアプリによって端末の動作や処理が妨害される恐れがあります。"</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"アカウント"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"利用可能なアカウントにアクセスします。"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"登録したフィードの読み取り"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"現在同期されているフィードの詳細を取得することをアプリに許可します。"</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMSメッセージの送信と表示"</string>
@@ -1061,7 +1059,7 @@
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g>を準備中"</string>
<string name="ext_media_checking_notification_message" msgid="4747432538578886744">"エラーを確認中"</string>
<string name="ext_media_new_notification_message" msgid="7589986898808506239">"新しい<xliff:g id="NAME">%s</xliff:g>が検出されました"</string>
- <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"写真などのメディアを転送するため"</string>
+ <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"写真などのメディア転送用"</string>
<string name="ext_media_unmountable_notification_title" msgid="8295123366236989588">"<xliff:g id="NAME">%s</xliff:g>は破損しています"</string>
<string name="ext_media_unmountable_notification_message" msgid="1586311304430052169">"<xliff:g id="NAME">%s</xliff:g>は破損しています。タップして解決してください。"</string>
<string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"対応していない<xliff:g id="NAME">%s</xliff:g>です"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 640d7bd..14f6426 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ფოტოებისა და ვიდეოების გადაღება"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ტელეფონი"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"სატელეფონო ზარების განხორციელება და მართვა"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"სენსორები"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"თქვენი სასიცოცხლო ფუნქციებისა და ფიზიკური აქტივობის ინფორმაციაზე წვდომა"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"სხეულის სენსორები"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"თქვენი სასიცოცხლო ფუნქციების შესახებ სენსორის მონაცემებზე წვდომა"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ფანჯრის კონტენტის მოძიება"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"შეამოწმეთ იმ ფანჯრის კონტექტი, რომელშიც მუშაობთ."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"„შეხებით აღმოჩენის“ ჩართვა"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"აპს შეეძლება MMS შეტყობინებების მიღება და დამუშავება. ეს ნიშნავს, რომ აპს შეეძლება შეტყობინებების მონიტორინგი და მათი წაშლა თქვენთვის ჩვენების გარეშე."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"მასიური დაგზავნის შეტყობინებების წაკითხვა"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"აპს შეეძლება, წაიკითხოს თქვენს მოწყობილობაზე გამოგზავნილი ქსელის სამაუწყებლო შეტყობინებები. სამაუწყებლო გაფრთხილებები მოგეწოდებათ ზოგიერთ ადგილზე ექსტრემალური სიტუაციების შესახებ გასაფრთხილებლად. ქსელის გადაუდებელი შეტყონიბენის მიღების დროს მავნე აპებმა შეიძლება ხელი შეუშალონ თქვენი მოწყობილობის ფუნქციონირებას ან ოპერაციებს."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"თქვენი ანგარიშები"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ხელმისაწვდომ ანგარიშებზე წვდომა."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"გამოწერილი არხების წაკითხვა"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"აპს შეეძლება ინფორმაციის მოპოვება ბოლოს სინქრონიზებული არხების შესახებ."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS-ის შეტყობინებების გაგზავნა და ნახვა"</string>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 21281f0..4785159 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"суретке түсіріп, бейне жазу"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"қоңырау шалу және телефон қоңырауларын басқару"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Сенсорлар"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"ағза күйінің көрсеткіштері мен дене белсенділігі туралы ақпаратқа қол жеткізу"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Дене датчиктері"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ағза күйінің көрсеткіштері туралы сенсор деректеріне қатынасу"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Терезе мазмұнын оқып отыру."</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Ашық тұрған терезе мазмұнын тексеру."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Түртілген элементтерді дыбыстау функциясын қосу"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Қолданбаға MMS хабарларын алу және өңдеу мүмкіндігін береді. Бұл қолданба құрылғыңызға жіберілген хабарларды сізге көрсетпестен қабылдай және жоя алады дегенді білдіреді."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ұялы хабар тарату хабарларын оқу"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Қолданбаға ұялы таратылым хабарларын оқу мүмкіндігін береді. Ұялы таратылым дабылдары кейбір аймақтарда төтенше жағдай туралы ескерту үшін қолданылады. Төтенше ұялы хабарлар келгенде залалды қолданбалар құрылғының жұмысына кедергі жасауы мүмкін."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Сіздің есептік жазбаларыңыз"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Қол жетімді есептік жазбаларға кіру."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"жазылған ағындарды оқу"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Қолданбаға қазіргі уақытта синхрондалған арналар туралы мәліметтерді алуға рұқсат береді."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS хабарларын жіберу және көру"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 95d6fbf..ebde5d7 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ថតរូប និងថតវីដេអូ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ទូរស័ព្ទ"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ហៅទូរស័ព្ទ និងគ្រប់គ្រងការហៅទូរស័ព្ទ"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"ឧបករណ៍ចាប់សញ្ញា"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"ចូលដំណើរការព័ត៌មានអំពីស្ថានភាពសុខភាព និងសកម្មភាពរាងកាយរបស់អ្នក"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"ឧបករណ៍ចាប់សញ្ញារាងកាយ"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ចូលដំណើរការទិន្នន័យឧបករណ៍ចាប់សញ្ញាអំពីស្ថានភាពសុខភាពរបស់អ្នក"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ទៅ​យក​មាតិកា​បង្អួច"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ពិនិត្យ​មាតិកា​បង្អួច​ដែល​អ្នក​កំពុង​ទាក់ទង​ជា​មួយ។"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"បើក​ការ​រក​មើល​​ដោយ​ប៉ះ"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"ឲ្យ​កម្មវិធី​ទទួល និង​ដំណើរការ​​សារ​ MMS ។ វា​មាន​ន័យ​ថា កម្មវិធី​អាច​តាមដាន​ ឬ​លុប​សារ​ដែល​បាន​ផ្ញើ​ទៅ​ឧបករណ៍​របស់​អ្នក​ដោយ​មិន​បង្ហាញ​ពួកវា។"</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"អាន​សារ​ប្រកាស​ចល័ត"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ឲ្យ​កម្មវិធី​អាន​សារ​ប្រកាស​ការ​ហៅ​ដែល​ឧបករណ៍​របស់​​អ្នក​បាន​ទទួល។ ការ​ជូន​ដំណឹង​ប្រកាស​ចល័ត​ត្រូវ​បាន​បញ្ជូន​ទៅ​ទីតាំង​មួយ​ចំនួន ដើម្បី​ព្រមាន​អ្នក​អំពី​ស្ថានភាព​អាសន្ន។ កម្មវិធី​ព្យាបាទ​អាច​ជ្រៀតជ្រែក​ការ​អនុវត្ត ឬ​ប្រតិបត្តិការ​ឧបករណ៍​របស់​អ្នក​​ពេល​ទទួល​ការ​ប្រកាស​ចល័ត​ពេល​អាសន្ន។"</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"គណនី​របស់​អ្នក"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ចូល​ដំណើរការ​គណនី​ដែល​មាន។"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"អាន​អត្ថបទ​ព័ត៌មាន​បាន​ជាវ"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ឲ្យ​កម្មវិធី​ទទួល​ព័ត៌មាន​លម្អិត​អំពី​អត្ថបទ​ព័ត៌មាន​​បាន​ធ្វើ​សម​កាល​កម្ម​បច្ចុប្បន្ន។"</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"ផ្ញើ និងមើលសារ SMS"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 96c6b4f..915f610 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ಚಿತ್ರಗಳನ್ನು ತೆಗೆಯಿರಿ ಹಾಗೂ ವೀಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ಫೋನ್"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಿ ಮತ್ತು ನಿರ್ವಹಿಸಿ"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"ಸಂವೇದಕಗಳು"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"ನಿಮ್ಮ ಮಹತ್ವಪೂರ್ಣ ಚಿಹ್ನೆಗಳು ಮತ್ತು ದೈಹಿಕ ಚಟುವಟಿಕೆ ಕುರಿತ ಮಾಹಿತಿಯನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"ದೇಹ ಸೆನ್ಸರ್‌ಗಳು"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ನಿಮ್ಮ ಮುಖ್ಯ ಲಕ್ಷಣಗಳ ಕುರಿತು ಸೆನ್ಸಾರ್ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ವಿಂಡೋ ವಿಷಯವನ್ನು ಹಿಂಪಡೆದುಕೊಳ್ಳುತ್ತದೆ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ನೀವು ಸಂವಹನ ನಡೆಸುತ್ತಿರುವ ವಿಂಡೋದ ವಿಷಯವನ್ನು ಪರೀಕ್ಷಿಸಿ."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ಸ್ಪರ್ಶಿಸುವ ಮೂಲಕ ಎಕ್ಸ್‌ಪ್ಲೋರ್ ಆನ್ ಮಾಡಿ"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMS ಸಂದೇಶಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಮತ್ತು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಇದರರ್ಥ, ನಿಮ್ಮ ಸಾಧನಕ್ಕೆ ಕಳುಹಿಸಲಾಗಿರುವ ಸಂದೇಶಗಳನ್ನು ನಿಮಗೆ ತೋರಿಸದೆಯೇ, ಅಪ್ಲಿಕೇಶನ್ ಅವುಗಳನ್ನು ಮಾನಿಟರ್ ಮಾಡಬಹುದು ಅಥವಾ ಅಳಿಸಬಹುದು."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ಸೆಲ್ ಪ್ರಸಾರದ ಸಂದೇಶಗಳನ್ನು ಓದಿರಿ"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ನಿಮ್ಮ ಸಾಧನದಿಂದ ಸ್ವೀಕರಿಸಿದ ಸೆಲ್ ಪ್ರಸಾರ ಸಂದೇಶಗಳನ್ನು ರೀಡ್ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್‌‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಸೆಲ್ ಪ್ರಸಾರ ಎಚ್ಚರಿಕೆಗಳನ್ನು ತುರ್ತು ಸಂದರ್ಭಗಳಲ್ಲಿ ನಿಮಗೆ ಎಚ್ಚರಿಸುವ ಸಲುವಾಗಿ ಕೆಲವು ಸ್ಥಳಗಳಲ್ಲಿ ವಿತರಿಸಲಾಗುತ್ತದೆ. ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್‌‌‌ಗಳು ತುರ್ತು ಸೆಲ್ ಪ್ರಸಾರವನ್ನು ಸ್ವೀಕರಿಸುವಾಗ, ನಿಮ್ಮ ಸಾಧನದ ಕಾರ್ಯಕ್ಷಮತೆ ಇಲ್ಲವೇ ಕಾರ್ಯಾಚರಣೆಯಲ್ಲಿ ಹಸ್ತಕ್ಷೇಪ ಮಾಡಬಹುದು."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"ನಿಮ್ಮ ಖಾತೆಗಳು"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ಲಭ್ಯವಿರುವ ಖಾತೆಗಳನ್ನು ಪ್ರವೇಶಿಸಿ."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ಚಂದಾದಾರ ಫೀಡ್‌ಗಳನ್ನು ಓದಿ"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ಪ್ರಸ್ತುತವಾಗಿ ಸಿಂಕ್‌ ಮಾಡಲಾದ ಫೀಡ್‌ಗಳ ಕುರಿತು ವಿವರಗಳನ್ನು ಪಡೆಯಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಿ ಮತ್ತು ನಿರ್ವಹಿಸಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 086f1ed..7a658a9 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"사진 찍기 및 동영상 녹화"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"전화"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"전화 걸기 및 관리"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"센서"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"생체 신호 및 물리적 활동 정보에 액세스합니다."</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"신체 센서"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"생체 신호에 관한 센서 데이터에 액세스"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"창 콘텐츠 가져오기"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"상호작용 중인 창의 콘텐츠를 검사합니다."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"터치하여 탐색 사용"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"앱이 MMS 메시지를 수신하고 처리할 수 있도록 허용합니다. 이는 앱이 사용자에게 표시하지 않고 기기로 전송된 메시지를 모니터링 또는 삭제할 수도 있다는 것을 의미합니다."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"셀 브로드캐스트 메시지 읽기"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"앱이 기기가 수신한 셀 브로드캐스트 메시지를 읽을 수 있도록 합니다. 비상 상황임을 알리기 위해 일부 지역에서 셀 브로드캐스트 경고가 전달됩니다. 비상 셀 브로드캐스트를 수신할 때 악성 앱이 기기의 성능이나 작동을 방해할 수 있습니다."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"계정"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"사용 가능한 계정에 액세스합니다."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"가입된 피드 읽기"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"앱이 현재 동기화된 피드에 대한 세부정보를 가져올 수 있도록 허용합니다."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS 메시지 전송 및 보기"</string>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index f86f171..fee26ee 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -351,8 +351,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"сүрөт тартуу жана видео жаздыруу"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"телефон чалуу жана аларды башкаруу"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Сенсорлор"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"олуттуу белгилериңиз жана физикалык аракетиңиз тууралуу маалыматка кирүү"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Дене сенсорлору"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"организмдин абалына көз салган сенсордун дайындарына мүмкүнчүлүк алуу"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Терезе мазмунун алуу"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Сиз иштеп жаткан терезенин мазмунун изилдөө."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Сыйпалап изилдөөнү жандыруу"</string>
@@ -382,10 +382,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Колдонмого MMS билдирүүлөрүн кабыл алууга жана аларды иштетип чыгууга уруксат берет. Бул, колдонмо сизге билгизбестен түзмөгүңүзгө жөнөтүлгөн билдирүүлөрдү мониторлой же жок кыла алат дегенди билдирет."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"уюктук берүү билдирүүлөрүн окуу"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Колдонмого түзмөгүңүз кабыл алган уюк берүүнүн билдирүүлөрүн окууга жол берет. Шашылыш эскертүү билдирүүлөрү кээ бир жерлердеги өзгөчө кырдаалдар тууралу сизди эскертүү үчүн жөнөтүлөт. Зыяндуу колдономолор шашылыш эскертүүлөр берилип жатканда, сиздин түзмөктүн иштешине жолтоо болушу мүмкүн."</string>
- <!-- no translation found for permgrouplab_accounts (3359646291125325519) -->
- <skip />
- <!-- no translation found for permgroupdesc_accounts (4948732641827091312) -->
- <skip />
<!-- no translation found for permlab_subscribedFeedsRead (4756609637053353318) -->
<skip />
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Колдонмого учурда шайкештештирилген каналдардын чоо-жайларын алуу мүмкүнчүлүгүн берет."</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 19f069f..6082348 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ຖ່າຍ​ຮູບ ແລະ​ບັນ​ທຶກວິ​ດີ​ໂອ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ໂທລະສັບ"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ໂທ ແລະ​ຈັດ​ການ​ການ​ໂທ​ລະ​ສັບ"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"ເຊັນເຊີ"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"ເຂົ້າເຖິງຂໍ້ມູນກ່ຽວກັບສັນຍານຊີບ ແລະກິດຈະກຳທາງຮ່າງກາຍຂອງທ່ານ"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"ເຊັນ​ເຊີ​ຮ່າງ​ກາຍ"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ເຂົ້າ​ຫາ​ຂໍ້​ມູນ​ເຊັນ​ເຊີ​ກ່ຽວ​ກັບ​ສັນ​ຍານ​ຊີບ​ຂອງ​ທ່ານ"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ດຶງຂໍ້ມູນເນື້ອຫາໃນໜ້າຈໍ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ກວດກາເນື້ອຫາຂອງໜ້າຈໍທີ່ທ່ານກຳລັງມີປະຕິສຳພັນນຳ."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ເປີດໃຊ້ \"ການສຳຫຼວດໂດຍສຳພັດ\""</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"ອະນຸຍາດໃຫ້ແອັບຯ ຮັບແລະປະມວນຜົນຂໍ້ຄວາມ MMS. ນີ້ໝາຍຄວາມວ່າແອັບຯສາມາດຕິດຕາມ ຫຼືລຶບຂໍ້ຄວາມທີ່ສົ່ງເຂົ້າອຸປະກອນຂອງທ່ານ ໂດຍທີ່ບໍ່ສະແດງພວກມັນໃຫ້ທ່ານເຫັນ."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ອ່ານຂໍ້ຄວາມກະຈາຍສັນຍານຂອງເສົາສັນຍານ"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ອະນຸຍາດໃຫ້ແອັບຯ ສາມາດອ່ານຂໍ້ຄວາມແຈ້ງເຕືອນເຫດສຸກເສີນ ທີ່ໄດ້ຮັບໂດຍອຸປະກອນຂອງທ່ານ. ການແຈ້ງເຕືອນສຸກເສີນທີ່ມີໃຫ້ບໍລິການໃນບາງພື້ນທີ່ ເພື່ອແຈ້ງເຕືອນໃຫ້ທ່ານຮູ້ເຖິງສະຖານະການສຸກເສີນ. ແອັບພລິເຄຊັນທີ່ເປັນອັນຕະລາຍອາດລົບກວນປະສິດທິພາບ ຫຼືການດຳເນີນງານຂອງອຸປະກອນຂອງທ່ານ ເມື່ອໄດ້ການຮັບແຈ້ງເຕືອນສຸກເສີນຈາກສະຖານີມືຖື."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"ບັນຊີຂອງທ່ານ"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ເຂົ້າເຖິງບັນຊີທີ່ໃຊ້ໄດ້."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ອ່ານຂໍ້ມູນຟີດທີ່ສະໝັກໄວ້"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ອະນຸຍາດໃຫ້ແອັບຯ ດຶງລາຍລະອຽດກ່ຽວກັບຂໍ້ມູນທີ່ກຳລັງຊິ້ງຢູ່."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"ສົ່ງ ແລະ​ເບິ່ງ​ຂໍ້​ຄວາມ SMS"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index f81bf66..65215de 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -231,7 +231,7 @@
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktai"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"pasiekti kontaktus"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Vietovė"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"galimybė pasiekti įrenginio vietovės informaciją"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"pasiekti įrenginio vietovės informaciją"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendorius"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"pasiekti kalendorių"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
@@ -244,8 +244,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"fotografuoti ir filmuoti"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefonas"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"skambinti ir tvarkyti telefonų skambučius"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Jutikliai"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"pasiekti informaciją apie jūsų gyvybinius ženklus ir fizinę veiklą"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Kūno jutikliai"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"pasiekti jutiklių duomenis apie gyvybinius ženklus"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Gauti lango turinį"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Tikrinti lango, su kuriuo sąveikaujate, turinį."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Įjungti „Naršyti paliečiant“"</string>
@@ -272,8 +272,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Leidžiama programai gauti ir apdoroti MMS pranešimus. Tai reiškia, kad programa gali stebėti ir ištrinti į jūsų įrenginį siunčiamus pranešimus jums jų neparodžiusi."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"skaityti mobiliuoju transliuojamus pranešimus"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Programai leidžiama skaityti mobiliuoju transliuojamus pranešimus, gaunamus jūsų įrenginyje. Mobiliuoju transliuojami įspėjimai pristatomi kai kuriose vietose, kad įspėtų apie kritines situacijas. Kai gaunamas mobiliuoju transliuojamas pranešimas apie kritinę situaciją, kenkėjiškos programos gali trukdyti įrenginiui veikti ar jį naudoti."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Jūsų paskyros"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Pasiekite galimas paskyras."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"skaityti prenumeruojamus tiekimus"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Leidžiama programai gauti išsamios informacijos apie šiuo metu sinchronizuojamus sklaidos kanalus."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"siųsti ir peržiūrėti SMS pranešimus"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 1ca1a36..e370c75 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -243,8 +243,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"uzņemt attēlus un ierakstīt videoklipus"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Tālrunis"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"veikt un pārvaldīt tālruņa zvanus"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensori"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"piekļūt informācijai par jūsu dzīvības funkcijām un fizisko aktivitāti"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Ķermeņa sensori"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"piekļūt sensoru datiem par jūsu veselības rādījumiem"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Izgūt loga saturu."</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Skatīt tā loga saturu, ar kuru mijiedarbojaties."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktivizēt funkciju “Pārlūkot pieskaroties”."</string>
@@ -271,8 +271,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Ļauj lietotnei saņemt un apstrādāt multiziņas. Tas nozīmē, ka lietotne var pārraudzīt vai dzēst uz jūsu ierīci nosūtītos ziņojumus, neparādot tos jums."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"šūnu apraides ziņojumu lasīšana"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Ļauj lietotnei lasīt ierīcē saņemtos šūnu apraides ziņojumus. Šūnu apraides brīdinājumi tiek piegādāti dažās atrašanās vietās, lai brīdinātu jūs par ārkārtas situācijām. Ļaunprātīgas lietotnes var traucēt ierīces veiktspēju vai darbības, kad ir saņemts ārkārtas šūnas apraides ziņojums."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Jūsu konti"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Piekļūstiet pieejamajiem kontiem."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lasīt abonētās plūsmas"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Ļauj lietotnei iegūt informāciju par pašlaik sinhronizētajām plūsmām."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"sūtīt un skatīt īsziņas"</string>
@@ -530,8 +528,8 @@
<item msgid="8901098336658710359">"Mājas"</item>
<item msgid="869923650527136615">"Mobilais"</item>
<item msgid="7897544654242874543">"Darbā"</item>
- <item msgid="1103601433382158155">"Faksa numurs darbā"</item>
- <item msgid="1735177144948329370">"Faksa numurs mājās"</item>
+ <item msgid="1103601433382158155">"Darba fakss"</item>
+ <item msgid="1735177144948329370">"Mājas fakss"</item>
<item msgid="603878674477207394">"Peidžers"</item>
<item msgid="1650824275177931637">"Cits"</item>
<item msgid="9192514806975898961">"Pielāgots"</item>
@@ -573,8 +571,8 @@
<string name="phoneTypeHome" msgid="2570923463033985887">"Mājas"</string>
<string name="phoneTypeMobile" msgid="6501463557754751037">"Mobilais"</string>
<string name="phoneTypeWork" msgid="8863939667059911633">"Darbā"</string>
- <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Faksa numurs darbā"</string>
- <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Faksa numurs mājās"</string>
+ <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Darba fakss"</string>
+ <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Mājas fakss"</string>
<string name="phoneTypePager" msgid="7582359955394921732">"Peidžers"</string>
<string name="phoneTypeOther" msgid="1544425847868765990">"Cits"</string>
<string name="phoneTypeCallback" msgid="2712175203065678206">"Atzvanīšana"</string>
@@ -1048,7 +1046,7 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB savienojums MIDI režīmā"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Pievienots kā instalēšanas programma"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ir izveidots savienojums ar USB piederumu."</string>
- <string name="usb_notification_message" msgid="7347368030849048437">"Lai skatītu citas opcijas, pieskarieties šeit."</string>
+ <string name="usb_notification_message" msgid="7347368030849048437">"Citas opcijas"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Vai formatēt USB atmiņu?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Vai formatēt SD karti?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Visi USB atmiņā saglabātie faili tiks dzēsti. Šo darbību nevar atsaukt."</string>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index c7b8704..95d34f1 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"фотографирај и снимај видео"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"повикувај и управувај со телефонски повици"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Сензори"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"пристапува до информации за виталните знаци и физичката активност"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Телесни сензори"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"пристапи до податоците од сензорите за виталните знаци"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Врати содржина на прозорец"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Провери ја содржината на прозорецот со кој се комуницира."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Вклучи „Истражувај со допир“"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Овозможува апликацијата да прима и да обработува ММС пораки. Тоа значи дека апликацијата може да следи или да брише пораки испратени до вашиот уред без да ви ги прикаже вам."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"прочитај пораки за мобилно емитување"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Овозможува апликациите да ги читаат пораките за мобилно емитување што ги прима вашиот уред. Предупредувањата за мобилно емитување се доставуваат на некои локации, за да ве предупредат на итни ситуации. Злонамерните апликации може да пречат во ефикасноста или работењето на вашиот уред кога се прима емитување за итен случај."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Ваши сметки"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Пристапи кон достапните сметки."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"читај претплатени навестувања на содржина"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Дозволува апликацијата да добива детали за навестувања што се тековно синхронизирани."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"испрати и прикажи СМС-пораки"</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 6bf5f9dc..0dd62f3 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ചിത്രങ്ങളെടുത്ത് വീഡിയോ റെക്കോർഡുചെയ്യുക"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ഫോണ്‍"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ഫോൺ വിളിക്കുകയും നിയന്ത്രിക്കുകയും ചെയ്യുക"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"സെൻസറുകൾ"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"നിങ്ങളുടെ ജീവാധാര ലക്ഷണങ്ങളെയും ശാരീരിക പ്രവർത്തനത്തെയും കുറിച്ചുള്ള വിവരങ്ങൾ ആക്സസ് ചെയ്യുക"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"ബോഡി സെൻസറുകൾ"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"നിങ്ങളുടെ ജീവാധാര ലക്ഷണങ്ങളെ കുറിച്ചുള്ള സെൻസർ വിവരങ്ങൾ ആക്സസ് ചെയ്യുക"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"വിൻഡോ ഉള്ളടക്കം വീണ്ടെടുക്കുക"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"നിങ്ങൾ സംവദിക്കുന്ന ഒരു വിൻഡോയുടെ ഉള്ളടക്കം പരിശോധിക്കുക."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"സ്‌പർശനം വഴി പര്യവേക്ഷണം ചെയ്യുക ഓൺ ചെയ്യുക"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMS സന്ദേശങ്ങൾ നേടാനും പ്രോസസ്സുചെയ്യാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. നിങ്ങളുടെ ഉപകരണത്തിലേക്ക് അയയ്‌ക്കുന്ന സന്ദേശങ്ങൾ നിങ്ങൾക്ക് ദൃശ്യമാക്കാതെ തന്നെ അപ്ലിക്കേഷന് നിരീക്ഷിക്കാനോ ഇല്ലാതാക്കാനോ കഴിയുമെന്നാണ് ഇതിനർത്ഥം."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"സെൽ പ്രക്ഷേപണ സന്ദേശങ്ങൾ റീഡുചെയ്യുക"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"നിങ്ങളുടെ ഉപകരണത്തിൽ ലഭിച്ച സെൽ പ്രക്ഷേപണ സന്ദേശങ്ങൾ റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. അടിയന്തര സാഹചര്യങ്ങളെക്കുറിച്ച് നിങ്ങൾക്ക് മുന്നറിയിപ്പ് നൽകാനായി ചില ലൊക്കേഷനുകളിൽ നൽകപ്പെടുന്നവയാണ് സെൽ പ്രക്ഷേപണ അലേർട്ടുകൾ. ഒരു അടിയന്തര സെൽ പ്രക്ഷേപണം ലഭിക്കുമ്പോൾ, ക്ഷുദ്രകരമായ അപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ ഉപകരണത്തിന്റെ പ്രകടനമോ പ്രവർത്തനമോ തടസ്സപ്പെടുത്താനിടയുണ്ട്."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"നിങ്ങളുടെ അക്കൗണ്ടുകൾ"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ലഭ്യമായ അക്കൗണ്ടുകൾ ആക്‌സസ്സ് ചെയ്യുക."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"സബ്‌സ്ക്രൈബ് ചെയ്‌ത ഫീഡുകൾ വായിക്കുക"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"നിലവിൽ സമന്വയിപ്പിച്ച ഫീഡുകളെക്കുറിച്ചുള്ള വിശദാംശങ്ങൾ നേടുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS സന്ദേശങ്ങൾ അയയ്‌ക്കുകയും കാണുകയും ചെയ്യുക"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index a36340e..4f1050a 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"зураг авах, бичлэг хийх"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Утас"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"утасны дуудлага хийх, дуудлага удирдах"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Мэдрэгчүүд"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"тaны ерөнхий байдлыг үзүүлэх үзүүлэлт болон биеийн хүчний ноогдлын мэдээлэлд нэвтрэх"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Биеийн мэдрэгч"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"таны биеийн байдлын талаарх мэдрэгч бүхий өгөгдөлд нэвтрэх"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Цонхны контентыг авах"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Таны харилцан үйлчлэх цонхны контентоос шалгах."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Хүрч танихыг асаах"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Апп нь MMS мессежийг хүлээн авах болон гүйцэтгэх боломжтой. Ингэснээр апп нь таны төхөөрөмжрүү илгээсэн мессежийг танд үзүүлэхгүйгээр хянах болон устгаж чадна."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"үүрэн өргөн дамжууллын мессеж унших"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Апп нь таны төхөөрөмжийн хүлээн авсан үүрэн өргөн дамжуулах мессежийг унших боломжтой. Үүрэн өргөн дамжууллын мэдэгдэл нь яаралтай нөхцөл байдлыг анхааруулах зорилгоор зарим байршлуудад хүрдэг. Хортой апп нь яаралтай үүрэн өргөн дамжууллыг хүлээн авсан үед таны төхөөрөмжийн ажиллагаа болон чадамжид нөлөөлөх боломжтой."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Таны акаунт"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Боломжит акаунтад хандах."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"бүртгүүлсэн хангамжийг унших"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Апп нь одоогийн синк хийгдсэн хангамжийн талаарх мэдээллийг авах боломжтой."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS мессежийг илгээх, харах"</string>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 97a7d37..bfe7b10 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"चित्रे घ्या आणि व्हिडिओ रेकॉर्ड करा"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"फोन"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"फोन कॉल करा आणि व्यवस्थापित करा"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"सेन्सर"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"आपली महत्त्वपूर्ण चिन्हे आणि शारीरिक क्रियाकलाप याविषयी प्रवेश माहिती"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"शरीर सेन्सर"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"आपल्‍या महत्त्वाच्या मापनांविषयी सेन्सर डेटामध्‍ये प्रवेश करा"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"विंडो सामग्री पुनर्प्राप्त करा"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"आपण परस्‍परसंवाद करीत असलेल्‍या विंडोची सामग्री तपासा."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"स्पर्श करून अन्वेषण चालू करा"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMS संदेश प्राप्त करण्यास आणि त्यावर प्रक्रिया करण्यास अॅप ला अनुमती देते. म्हणजेच अॅप आपल्या डिव्हाइसवर पाठविलेले संदेश आपल्याला न दर्शवता त्यांचे परीक्षण करू किंवा ते हटवू शकतो."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"सेल प्रसारण संदेश वाचा"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"आपल्या डिव्हाइसद्वारे प्राप्त केलेले सेल प्रसारण संदेश वाचण्यासाठी अॅप ला अनुमती देते. काही स्थानांमध्ये आपल्याला आणीबाणीच्या परिस्थितीची चेतावणी देण्यासाठी सेल प्रसारण सूचना वितरीत केल्या जातात. आणीबाणी सेल प्रसारण प्राप्त होते तेव्हा आपल्या डिव्हाइसच्या कार्यप्रदर्शनात किंवा कार्यात दुर्भावनापूर्ण अॅप्स व्यत्यय आणू शकतात."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"आपली खाती"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"उपलब्ध खात्यांवर प्रवेश करा."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"सदस्यता घेतलेली फीड वाचा"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"सध्या संकालित केलेल्या फीडविषयी तपशील मिळविण्यासाठी अॅप ला अनुमती देते."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS संदेश पहा आणि व्यवस्थापित करा"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index ef51f45..5c58ee3 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ambil gambar dan rakam video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"buat dan urus panggilan telefon"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Penderia"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"akses maklumat tentang tanda vital dan aktiviti fizikal anda"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Penderia Badan"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"akses data penderia tentang tanda vital anda"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Dapatkan kembali kandungan tetingkap"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Periksa kandungan tetingkap yang berinteraksi dengan anda."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Hidupkan Jelajah melalui Sentuhan"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Membenarkan apl menerima dan memproses mesej MMS. Ini bermakna apl boleh memantau atau memadam mesej yang dihantar ke peranti anda tanpa menunjukkannya kepada anda."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"baca mesej siaran sel"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Membolehkan apl membaca mesej siaran sel yang diterima oleh peranti anda. Isyarat siaran sel dihantar di beberapa lokasi untuk memberi amaran kepada anda tentang situasi kecemasan. Apl hasad boleh mengganggu prestasi atau operasi peranti anda apabila siaran sel kecemasan diterima."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Akaun anda"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Akses akaun yang tersedia."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"baca suapan langganan"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Membenarkan apl mendapatkan butiran mengenai suapan tersegerak semasa."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"hantar dan lihat mesej SMS"</string>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 16a1121..f801558 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ဓာတ်ပုံ ရိုက်ပြီးနောက် ဗွီဒီယို မှတ်တမ်းတင်ရန်"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ဖုန်း"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ဖုန်းခေါ်ဆိုမှုများ ပြုလုပ်ရန်နှင့် စီမံရန်"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"အာရုံခံကိရိယာများ"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"သင်၏ အဓိကကျသောလက္ခဏာများနှင့် ရုပ်ပိုင်းဆိုင်ရာဆောင်ရွက်ချက်များအကြောင်း အချက်အလက်အား ဝင်ရောက်သုံးပါ"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"ခန္ဓာကိုယ် အာရုံခံကိရိယာများ"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"သင်၏ အဓိကကျသော လက္ခဏာများအကြောင်း အာရုံခံကိရိယာဒေတာကို ရယူသုံးစွဲရန်"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ဝင်းဒိုးမှာပါရှိသည်များကို ထုတ်ယူခြင်း"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"သင် အပြန်အလှန်လုပ်နေသော ဝင်းဒိုးမှာပါရှိသည်များကို သေချာစွာ ကြည့်ရှုစစ်ဆေးပါ"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ထိတို့ခြင်းဖြင့် ရှာဖွေပေးနိုင်တာကို ဖွင့်လိုက်ပါ"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"အပလီကေးရှင်းအား ရုပ်သံစာများ လက်ခံခြင်း၊ ဆောင်ရွက်ခြင်း ခွင့်ပြုပါ။ ဤခွင့်ပြုချက်တွင် အပလီကေးရှင်းအနေဖြင့် သင် လက်ခံရရှိသော စာများအား သင့်အား မပြပဲစောင့်ကြည့်ခွင့်နှင့် ဖျက်ပစ်ခွင့်များ ပါဝင်ပါသည်။"</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"စာတိုများ ဖြန့်ဝေခြင်းစနစ်အား ဖတ်ခြင်း"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"အပလီကေးရှင်းကို သင်၏ စက်ပစ္စည်းမှ လက်ခံရရှိသော အများလွှင့်ထုတ်ချက်များကို ဖတ်ရန် ခွင့်ပြုသည်။ အများလွှင့်ထုတ်ချက်များသည် အရေးပေါ်အခြေအနေများကို သင့်အား သတိပေးရန် အချို့ နေရာများတွင် ပို့ပေးသည်။ အရေးပေါ်သတိပေးချက် ထုတ်လွှင့်ချက်ကို လက်ခံရရှိချိန်တွင်အန္တရာယ် ဖြစ်စေနိုင်သော အပလီကေးရှင်းများသည် သင့်စက်ပစ္စည်း၏ လုပ်ငန်းလည်ပတ်မှုနှင့် စွမ်းဆောင်မှုကို ဝင်စွက်ဖက်နိုင်သည်။"</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"သင့်အကောင့်များ"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ရရိှနိုင်သောအကောင့်များကို အသုံးပြုရန်"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"အမည်သွင်းထားသောဖိဖ့်များကို ဖတ်ခြင်း"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"appအား လောလောဆယ် စင့်က် လုပ်ပြီးသား ထည့်သွင်းမှုများ ဆိုင်ရာ အသေးစိတ်များကို ရယူခွင့်ပြုသည်။"</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS စာများကို ပို့ကာ ကြည့်မည်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 1849d3e..c86fb56 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ta bilder og ta opp video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ring og administrer anrop"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorer"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"få tilgang til informasjon om livstegnene dine og den fysiske aktiviteten din"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Kroppssensorer"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"få tilgang til sensordata om de vitale tegnene dine"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"hente innhold i vinduer"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Den kontrollerer innholdet i vinduer du samhandler med."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"slå på berøringsutforsking"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Lar appen motta og behandle multimediemeldinger. Dette betyr at appen kan overvåke eller slette meldinger som er sendt til enheten din uten at du har sett dem."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lese kringkastede meldinger"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Tillater at appen kan lese kringkastede meldinger enheten din mottar. Kringkastede varsler leveres noen steder for å advare deg om nødsituasjoner. Skadelige apper kan forstyrre ytelsen eller funksjonen til enheten din når en kringkastet nødmelding mottas."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Google-kontoer"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Tilgang til tilgjengelige Google-kontoer."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lese abonnement på nyhetskilder"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Lar appen hente inn detaljer om strømmer som er synkroniserte for øyeblikket."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"sende og lese SMS-meldinger"</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index e3d795d..238acae 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"तस्बिर तथा भिडियो रेकर्ड गर्नुहोस्"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"फोन"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"फोन कलहरू गर्नुहोस् र व्यवस्थापन गर्नुहोस्"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"सेन्सरहरू"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"तपाईँको महत्त्वपूर्ण संकेत र शारीरिक गतिविधिबारे जानकारीको पहुँच गर्नुहोस्"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"शारीरिक सेन्सर"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"तपाईँको महत्त्वपूर्ण संकेत बारे सेन्सर डेटा पहुँच गर्नुहोस्"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"विन्डो सामग्रीको पुनःबहाली गर्नुहोस्।"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"तपाईँको अन्तरक्रिया भइरहेको विन्डोको सामग्रीको निरीक्षण गर्नुहोस्।"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"छोएर गरिने खोजलाई सुचारु गर्नुहोस्"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"अनुप्रयोगलाई MMS सन्देशहरू प्राप्त गर्न र प्रकृया गर्न अनुमति दिन्छ। यसको मतलब अनुप्रयोगले तपाईंको उपकरणमा पठाइएको सन्देशहरू तपाईंलाई नदेखाईनै मोनिटर गर्न वा मेटाउन सक्दछ।"</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"सेल प्रसारित सन्देशहरू पढ्नुहोस्"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"तपाईंको उपकरणद्वारा प्राप्त सेल प्रसारण सन्देशहरू अनुप्रयोगलाई पढ्न अनुमति दिन्छ। सेल प्रसारण चेतावनीहरू केही स्थानहरूमा तपाईंलाई आपतकालीन गतिविधिहरूको बारेमा सचेत गराउन गरिएका छन्। खराब अनुप्रयोगहरूले एउटा आपतकालीन सेल प्रसारण प्राप्त गर्दछ जब तपाईंको उपकरणको प्रदर्शन वा अपरेशनको साथ हस्तक्षेप गर्न सक्दछन्।"</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"तपाईँका खाताहरू"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"उपलब्ध खाताहरू पहुँच गर्नुहोस्।"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"सदस्य बनाइका फिडहरू पढ्नुहोस्"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"अनुप्रयोगलाई अहिलेको समीकरण गरिएका सूचकहरू बारे विवरणहरू लिने अनुमति दिन्छ।"</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS सन्देशहरू पठाउनुहोस् र हेर्नुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 57e29ea..3deb674 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"foto\'s maken en video opnemen"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefoon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"bellen en telefoontjes beheren"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensoren"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"toegang tot informatie over uw vitale functies en fysieke activiteit"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Lichaamssensoren"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"toegang tot sensorgegevens over uw vitale functies"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Inhoud van vensters ophalen"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"De inhoud inspecteren van een venster waarmee u interactie heeft."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"\'Verkennen via aanraking\' inschakelen"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Hiermee kan de app MMS-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar uw apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"infodienstberichten lezen"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Toestaan dat de app infodienstberichten leest die worden ontvangen op uw apparaat. Infodienstberichten worden verzonden naar bepaalde locaties om u te waarschuwen voor noodsituaties. Schadelijke apps kunnen de prestaties of verwerking van uw apparaat verstoren wanneer een infodienstbericht wordt ontvangen."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Uw accounts"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Toegang tot de beschikbare accounts."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"Geabonneerde feeds lezen"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Hiermee kan de app details over de huidige gesynchroniseerde feeds achterhalen."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"sms\'jes verzenden en bekijken"</string>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index a91578f..35001d3 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ਤਸਵੀਰਾਂ ਖਿੱਚੋ ਅਤੇ ਵੀਡੀਓ ਰਿਕਾਰਡ ਕਰੋ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ਫੋਨ"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ਫ਼ੋਨ ਕਾਲਾਂ ਕਰੋ ਅਤੇ ਉਹਨਾਂ ਨੂੰ ਪ੍ਰਬੰਧਿਤ ਕਰੋ"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"ਸੰੰਵੇਦਕ"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"ਆਪਣੇ ਮਹੱਤਵਪੂਰਣ ਲੱਛਣਾਂ ਅਤੇ ਸਰੀਰਕ ਗਤੀਵਿਧੀ ਬਾਰੇ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"ਸਰੀਰ ਸੰਵੇਦਕ"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ਆਪਣੇ ਮਹੱਤਵਪੂਰਣ ਲੱਛਣਾਂ ਬਾਰੇ ਸੰਵੇਦਕ ਡਾਟਾ ਤੱਕ ਪਹੁੰਚ"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ਵਿੰਡੋ ਸਮੱਗਰੀ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ਇੱਕ ਵਿੰਡੋ ਦੀ ਸਮੱਗਰੀ ਦੀ ਜਾਂਚ ਕਰੋ, ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਇੰਟਰੈਕਟ ਕਰ ਰਹੇ ਹੋ।"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ਐਕਸਪਲੋਰ ਬਾਇ ਟਚ ਚਾਲੂ ਕਰੋ"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"ਐਪ ਨੂੰ MMS ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸਦਾ ਮਤਲਬ ਹੈ ਕਿ ਐਪ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਤੇ ਭੇਜੇ ਗਏ ਸੁਨੇਹਿਆਂ ਨੂੰ ਤੁਹਾਨੂੰ ਦਿਖਾਏ ਬਿਨਾਂ ਨਿਰੀਖਣ ਕਰ ਸਕਦਾ ਹੈ ਜਾਂ ਮਿਟਾ ਸਕਦਾ ਹੈ।"</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ਸੈਲ ਪ੍ਰਸਾਰਨ ਸੁਨੇਹੇ ਪੜ੍ਹੋ"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਵੱਲੋਂ ਪ੍ਰਾਪਤ ਕੀਤੇ ਸੈਲ ਪ੍ਰਸਾਰਨ ਸੁਨੇਹੇ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸੈਲ ਪ੍ਰਸਾਰਨ ਚਿਤਾਵਨੀਆਂ ਤੁਹਾਨੂੰ ਐਮਰਜੈਂਸੀ ਸਥਿਤੀਆਂ ਦੀ ਚਿਤਾਵਨੀ ਦੇਣ ਲਈ ਕੁਝ ਨਿਰਧਾਰਿਤ ਸਥਾਨਾਂ ਤੇ ਪ੍ਰਦਾਨ ਕੀਤੀਆਂ ਜਾਂਦੀਆਂ ਹਨ। ਖ਼ਰਾਬ ਐਪਸ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਦੇ ਪ੍ਰਦਰਸ਼ਨ ਜਾਂ ਓਪਰੇਸ਼ਨ ਵਿੱਚ ਵਿਘਨ ਪਾ ਸਕਦੇ ਹਨ ਜਦੋਂ ਇੱਕ ਐਮਰਜੈਂਸੀ ਸੈਲ ਪ੍ਰਸਾਰਨ ਪ੍ਰਾਪਤ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।"</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"ਤੁਹਾਡੇ ਖਾਤੇ"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ਉਪਲਬਧ ਖਾਤਿਆਂ ਤੱਕ ਪਹੁੰਚ।"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ਸਬਸਕ੍ਰਾਈਬ ਕੀਤੇ ਫੀਡਸ ਪੜ੍ਹੋ"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ਐਪ ਨੂੰ ਵਰਤਮਾਨ ਵਿੱਚ ਸਿੰਕ ਕੀਤੇ ਫੀਡਸ ਬਾਰੇ ਵੇਰਵੇ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS ਸੁਨੇਹੇ ਭੇਜੋ ਅਤੇ ਦਿਖਾਓ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 0cd0e2b..999db25 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -244,8 +244,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"robienie zdjęć i nagrywanie filmów"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"nawiązywanie połączeń telefonicznych i zarządzanie nimi"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Czujniki"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"uzyskiwać dostęp do informacji o podstawowych funkcjach Twojego organizmu i Twojej aktywności fizycznej"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Czujniki na ciele"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"dostęp do danych czujnika podstawowych funkcji życiowych"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pobieranie zawartości okna"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Sprawdzanie zawartości okna, z którego korzystasz."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Włączenie czytania dotykiem"</string>
@@ -272,8 +272,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Pozwala aplikacji na odbieranie i przetwarzanie MMS-ów. To oznacza, że aplikacja będzie mogła bez Twojej wiedzy monitorować i usuwać wiadomości wysyłane do Twojego urządzenia."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"odczyt komunikatów z sieci komórkowej"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Zezwala aplikacji na odczyt komunikatów z sieci komórkowej odebranych na urządzeniu. Komunikaty alarmowe z sieci komórkowej są dostarczane w niektórych lokalizacjach w celu ostrzeżenia Cię o sytuacjach zagrożenia. Złośliwe aplikacje mogą wpływać na wydajność lub zakłócać działanie urządzenia po odebraniu komunikatu alarmowego z sieci komórkowej."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Twoje konta"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Dostęp do udostępnionych kont."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"czytanie subskrybowanych źródeł"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Pozwala aplikacji na pobieranie szczegółowych informacji na temat obecnie zsynchronizowanych kanałów."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"wysyłać i wyświetlać SMS-y"</string>
@@ -1228,7 +1226,7 @@
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
<string name="activitychooserview_choose_application" msgid="2125168057199941199">"Wybierz aplikację"</string>
<string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Nie udało się uruchomić aplikacji <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
- <string name="shareactionprovider_share_with" msgid="806688056141131819">"Udostępnij przez"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Udostępnij przez:"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Udostępnij przez <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Uchwyt przesuwny. Dotknij i przytrzymaj."</string>
<string name="description_target_unlock_tablet" msgid="3833195335629795055">"Przesuń, aby odblokować."</string>
@@ -1275,7 +1273,7 @@
<string name="sha1_fingerprint" msgid="7930330235269404581">"Odcisk cyfrowy SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Zobacz wszystkie"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Wybierz działanie"</string>
- <string name="share_action_provider_share_with" msgid="5247684435979149216">"Udostępnij przez"</string>
+ <string name="share_action_provider_share_with" msgid="5247684435979149216">"Udostępnij przez:"</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
<string name="sending" msgid="3245653681008218030">"Wysyłanie..."</string>
<string name="launchBrowserDefault" msgid="2057951947297614725">"Uruchomić przeglądarkę?"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 3d6d4fd..ca57cfc 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"tirar fotografias e gravar vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telemóvel"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"fazer e gerir chamadas"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensores"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"aceder a informações acerca dos seus sinais vitais e da atividade física"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensores de corpo"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"aceder a dados do sensor acerca dos seus sinais vitais"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Obter conteúdo da janela"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecionar o conteúdo de uma janela com a qual está a interagir."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ativar Explorar Através do Toque"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permite que a aplicação receba e processe mensagens MMS. Isto significa que a aplicação poderá monitorizar ou eliminar mensagens enviadas para o seu dispositivo sem as apresentar."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ler mensagens de transmissão celular"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite que a aplicação leia mensagens de transmissão celular recebidas pelo seu dispositivo. Os alertas de transmissão celular são fornecidos em algumas localizações para avisá-lo sobre situações de emergência. As aplicações maliciosas podem interferir com o desempenho ou funcionamento do seu dispositivo quando for recebida uma transmissão celular de emergência."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"As suas contas"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Aceda às contas disponíveis."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ler feeds subscritos"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permite à aplicação obter detalhes acerca dos feeds atualmente sincronizados."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"enviar e ver mensagens SMS"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 600a659..897ddfb 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"tirar fotos e gravar vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefone"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"fazer e gerenciar chamadas telefônicas"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensores"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"acessar informações sobre seus sinais vitais e atividade física"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensores corporais"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"acessar dados do sensor sobre seus sinais vitais"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar cont. da janela"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecionar o conteúdo da janela com que você está interagindo."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ativar Explorar por toque"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permite que o app receba e processe mensagens MMS. Isso significa que o app pode monitorar ou excluir as mensagens enviadas para o dispositivo sem mostrá-las para você."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ler mensagens de difusão celular"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite que o app leia mensagens de difusão celular recebidas por seu dispositivo. Alertas de difusão celular são recebidos em alguns locais para avisar você de situações de emergência. Apps maliciosos podem interferir no desempenho ou funcionamento de seu dispositivo quando uma difusão celular de emergência é recebida."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Suas contas"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Acessar as contas disponíveis."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ler feeds inscritos"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permite que o app obtenha detalhes sobre os feeds sincronizados no momento."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"enviar e ver mensagens SMS"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 984c57d..bf483da 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -243,8 +243,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"fotografiază și înregistrează videoclipuri"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"inițiază și gestionează apeluri telefonice"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Senzori"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"accesează informații despre semnele vitale și activitatea fizică"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Senzori corporali"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accesează datele înregistrate de senzori despre semnele vitale"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperează conținutul ferestrei"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspectează conținutul unei ferestre cu care interacționați."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activează funcția Explorați prin atingere"</string>
@@ -271,8 +271,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permite aplicației să primească și să proceseze mesaje MMS. Acest lucru înseamnă că aplicația ar putea monitoriza sau şterge mesajele trimise pe dispozitivul dvs. fără a vi le arăta."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"citeşte mesajele cu transmisie celulară"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite aplicației să citească mesajele primite prin transmisie celulară de dispozitivul dvs. Alertele cu transmisie celulară sunt difuzate în unele locaţii pentru a vă avertiza cu privire la situaţiile de urgenţă. Aplicaţiile rău intenţionate pot afecta performanţa sau funcţionarea dispozitivului dvs. când este primită o transmisie celulară de urgenţă."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Conturile dvs."</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Accesează conturile disponibile."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"citire feeduri abonat"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permite aplicației să obţină detalii despre feedurile sincronizate în prezent."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"trimite și vede mesajele SMS"</string>
@@ -918,7 +916,7 @@
<string name="screen_compat_mode_hint" msgid="1064524084543304459">"Reactivaţi acest mod din Setări de sistem &gt; Aplicaţii &gt; Descărcate."</string>
<string name="smv_application" msgid="3307209192155442829">"Aplicaţia <xliff:g id="APPLICATION">%1$s</xliff:g> (procesul <xliff:g id="PROCESS">%2$s</xliff:g>) a încălcat propria politică StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Procesul <xliff:g id="PROCESS">%1$s</xliff:g> a încălcat propria politică StrictMode."</string>
- <string name="android_upgrading_title" msgid="1584192285441405746">"Android trece la o vers. superioară..."</string>
+ <string name="android_upgrading_title" msgid="1584192285441405746">"Android trece la o versiune superioară..."</string>
<string name="android_start_title" msgid="8418054686415318207">"Android pornește..."</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Se optimizează stocarea."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Se optimizează aplicația <xliff:g id="NUMBER_0">%1$d</xliff:g> din <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index f453011..eabfdb8 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -244,8 +244,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"фото- и видеосъемка"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"осуществление телефонных звонков и управление ими"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Датчики"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"доступ к основным показателям состояния организма и сведениям о физической активности"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Нательные датчики"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"доступ к данным датчиков о состоянии организма"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Получать содержимое окна"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Анализировать содержимое активного окна."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Включать аудиоподсказки"</string>
@@ -272,8 +272,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Приложение сможет получать и обрабатывать MMS. Это значит, что оно сможет отслеживать и удалять отправленные на ваше устройство сообщения, не показывая их."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"Читать сообщения массовой рассылки"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Приложение получит доступ к сообщениям широковещательных SMS-служб, которые в некоторых странах используются для информирования населения об экстренных ситуациях. Вредоносные программы могут помешать работе устройства, на которое поступают такие сообщения."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Ваши аккаунты"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Доступ к имеющимся аккаунтам."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"Просмотр фидов пользователя"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Приложение сможет получать сведения о синхронизируемых в настоящее время фидах."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"отправка и просмотр SMS-сообщений"</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index b2a2b5d..3594fd4 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"පින්තූර ගැනීම සහ වීඩියෝ පටිගත කිරීම"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"දුරකථනය"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"දුරකථන ඇමතුම් සිදු කිරීම සහ කළමනාකරණය කිරීම"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"සංවේදක"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"ඔබේ ජෛව ලක්ෂණ සහ ශාරීරික ක්‍රියාකාරකම් පිළිබඳ ප්‍රවේශ තොරතුරු"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"ශරීර සංවේදක"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ඔබේ ජෛව ලක්ෂණ පිළිබඳ සංවේදක දත්ත වෙත පිවිසෙන්න"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"කවුළු අන්න්තර්ගතය ලබාගන්න"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ඔබ අන්තර්ක්‍රියාකාරී වන කවුළුවේ අන්තර්ගතය පරීක්ෂා කරන්න."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ස්පර්ශයෙන් ගවේෂණය සක්‍රිය කරන්න"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMS පණිවිඩ සොයා ලබාගැනීමට සහ ක්‍රියාත්මක කිරීමට යෙදුමට අවසර දෙන්න. යෙදුම නිරීක්ෂණය කරනු ලබන අතර ඔබට ලැබුන පණිවිඩ පෙන්වීමෙන් තොරවම මකා දැමිය හැකි බව මෙමඟින් අදහස් කරයි."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"සෙල් ප්‍රචාරණ පණිවිඩ කියවීම"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ඔබගේ උපාංගයට ලැබුණු සෙල් විකාශන පණිවිඩ කියවීමට යෙදුමට අවසර දෙන්න. ඔබට හදිසි අවස්ථාවන් පිළිබඳ අනතුරු ඇඟවීමට සෙල් විකාශන පණිවිඩ ඇතැම් ස්ථානවල සිට යවනු ලබයි. හදිසි සෙල් විකාශන ලැබෙන අවස්ථාවකදී, අනිෂ්ට යෙදුම් මඟින් ඔබගේ උපාංගයට කාර්ය සාධනයට හෝ ක්‍රියකරණයට බාධා සිදුවිය හැක."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"ඔබගේ ගිණුම්"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ලබාගත හැකි ගිණුම් වලට ප්‍රවේශ වීම."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"දායක වූ සංග්‍රහ කියවීම"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"වර්තමාන සමමුහුර්ත සංග්‍රහ ගැන විස්තර ලැබීමට යෙදුමට අවසර දෙන්න."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS පණිවිඩ යැවීම සහ බැලීම"</string>
@@ -368,7 +366,7 @@
<string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"ටැබ්ලටයේ අධෝරක්ත සම්ප්‍රේෂකය භාවිතයට යෙදුමට ඉඩ දෙන්න."</string>
<string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"යෙදුමට රූපවාහිනියේ අධෝරක්ත සම්ප්‍රේෂකය භාවිතා කිරීමට අවසර දෙයි."</string>
<string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"දුරකථනයේ අධෝරක්ත සම්ප්‍රේෂකය භාවිතයට යෙදුමට ඉඩ දෙන්න."</string>
- <string name="permlab_setWallpaper" msgid="6627192333373465143">"බිතුපත සැකසීම"</string>
+ <string name="permlab_setWallpaper" msgid="6627192333373465143">"වෝල්පේපරය සැකසීම"</string>
<string name="permdesc_setWallpaper" msgid="7373447920977624745">"පද්ධති බිතුපත සැකසීමට යෙදුමට අවසර දෙන්න."</string>
<string name="permlab_setWallpaperHints" msgid="3278608165977736538">"ඔබගේ බිතුපතේ ප්‍රමාණය සැකසීම"</string>
<string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"පද්ධති බිතුපතේ ප්‍රමාණ ඉඟි සකස් කිරීමට යෙදුමට අවසර දෙන්න."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 8e38c0c..96df345 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -235,7 +235,7 @@
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendár"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"prístup ku kalendáru"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="4656988620100940350">"posielanie a zobrazovanie správ SMS"</string>
+ <string name="permgroupdesc_sms" msgid="4656988620100940350">"posielať a zobrazovať SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Úložisko"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"prístup k fotkám, médiám a súborom na zariadení"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofón"</string>
@@ -243,9 +243,9 @@
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fotoaparát"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"fotenie a zaznamenávanie videí"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefón"</string>
- <string name="permgroupdesc_phone" msgid="6234224354060641055">"telefonovanie a správa hovorov"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Senzory"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"prístup k informáciám o vašich životných funkciách a fyzickej aktivite"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"telefonovať a spravovať hovory"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Telesné senzory"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"prístup k údajom senzorov o životných funkciách"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Načítať obsah okna"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Môžete preskúmať obsah okna, s ktorým pracujete."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Zapnúť funkciu Preskúmanie dotykom"</string>
@@ -272,11 +272,9 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Umožňuje aplikácii prijímať a spracovávať správy MMS. Znamená to, že aplikácia môže sledovať správy odoslané na vaše zariadenie alebo ich odstrániť bez toho, aby sa vám zobrazili."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"čítať správy Cell Broadcast"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Umožňuje aplikácii čítať správy Cell Broadcast prijaté vaším zariadením. Upozornenia Cell Broadcast sú doručované na určitých miestach a upozorňujú na núdzové situácie. Škodlivé aplikácie môžu pri prijatí núdzovej správy Cell Broadcast narušiť výkonnosť alebo prevádzku vášho zariadenia."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Vaše účty"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Prístup k dostupným účtom."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"čítať odoberané informačné kanály"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Umožňuje aplikácii získať podrobnosti o aktuálne synchronizovaných informačných kanáloch."</string>
- <string name="permlab_sendSms" msgid="7544599214260982981">"posielať a zobrazovať správy SMS"</string>
+ <string name="permlab_sendSms" msgid="7544599214260982981">"posielať a zobrazovať SMS"</string>
<string name="permdesc_sendSms" msgid="7094729298204937667">"Umožňuje aplikácii odosielať správy SMS. Môže to mať za následok účtovanie neočakávaných poplatkov. Škodlivé aplikácie vám môžu spôsobiť výdavky odosielaním správ bez vášho potvrdenia."</string>
<string name="permlab_readSms" msgid="8745086572213270480">"čítať textové správy (SMS alebo MMS)"</string>
<string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Umožňuje aplikácii čítať správy SMS uložené v tablete alebo na SIM karte. Toto povolenie umožňuje aplikácii čítať správy SMS bez ohľadu na ich obsah alebo dôvernosť."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 5a4c4da..0568568 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -244,8 +244,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"fotografiranje in snemanje videoposnetkov"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"opravljanje in upravljanje telefonskih klicev"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Tipala"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"dostop do podatkov o vaših vitalnih znakih in fizični dejavnosti"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Tipala telesnih funkcij"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"dostop do podatkov tipala o vaših vitalnih znakih"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pridobiti vsebino okna"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Preverjanje vsebine okna, ki ga uporabljate."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Vklopiti raziskovanje z dotikom"</string>
@@ -272,8 +272,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Aplikaciji omogoča prejemanje in obdelavo MMS-ov. S tem lahko aplikacija nadzoruje ali izbriše sporočila, poslana v napravo, ne da bi vam jih pokazala."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"branje sporočil oddaje v celici"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Omogoča aplikaciji branje sporočil oddaje v celici, ki jih prejme naprava. Opozorila oddaje v celici so dostavljena na nekaterih lokacijah, da vas opozorijo na izredne razmere. Zlonamerne aplikacije lahko vplivajo na delovanje naprave, ko dobi sporočilo oddaje v celici."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Vaši računi"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Dostop do razpoložljivih računov."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"branje naročenih virov"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Aplikaciji omogoča dobivanje podrobnosti o trenutno sinhroniziranih virih."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"pošiljanje in ogled sporočil SMS"</string>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index 3cb5c51..257516e 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"bëj fotografi dhe regjistro video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefoni"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"kryej dhe menaxho telefonata"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorët"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"qasu tek informacionet për shenjat jetësore dhe aktivitetin tënd fizik"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensorët e trupit"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"qasu tek të dhënat e sensorëve rreth shenjave të tua jetësore"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Nxjerrë përmbajtjen e dritares"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspekton përmbajtjen e dritares me të cilën po ndërvepron."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktivizojë funksionin \"Eksploro me prekje\""</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Lejon aplikacionin të marrë dhe përpunojë mesazhe MMS. Kjo do të thotë se aplikacioni mund të monitorojë ose fshijë mesazhe të dërguara në pajisjen tënde, pa t\'i treguar ato."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lexo mesazhet e transmetimit të qelizës"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Lejon aplikacionin të lexojë mesazhet e transmetimit të qelizës, të marra nga pajisja jote. Alarmet e transmetimit të qelizës dërgohen në disa vendndodhje për të të paralajmëruar në situata urgjente. Aplikacionet keqdashëse mund të ndërhyjnë në veprimtarinë ose operacionin e pajisjes tënde kur merret një transmetim urgjent i qelizës."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Llogaritë e tua"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Qasje në llogaritë e vlefshme."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lexo informacione të abonuara"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Lejon aplikacionin të marrë detaje rreth çdo gjëje që sinkronizohet në pajisje."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"dërgo dhe shiko mesazhet SMS"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index d2106a7..a361389 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -243,8 +243,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"снимање слика и видео снимака"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"упућивање телефонских позива и управљање њима"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Сензори"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"приступ информацијама о виталним функцијама и физичким активностима"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Сензори за тело"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"приступ подацима сензора о виталним функцијама"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Преузима садржај прозора"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Проверава садржај прозора са којим остварујете интеракцију."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Укључивање Истраживања додиром"</string>
@@ -271,8 +271,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Дозвољава апликацији да прима и обрађује MMS поруке. То значи да апликација може да надгледа или брише поруке које се шаљу уређају, а да вам их не прикаже."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"читање порука инфо сервиса"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Омогућава апликацији да чита поруке инфо сервиса које уређај прима. Упозорења инфо сервиса се на неким локацијама примају као упозорења на хитне случајеве. Злонамерне апликације могу да утичу на учинак или ометају функционисање уређаја када се прими порука инфо сервиса о хитном случају."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Налози"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Приступ доступним налозима."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"читање пријављених фидова"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Дозвољава апликацији да преузима детаље о тренутно синхронизованим фидовима."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"шаљи и прегледај SMS поруке"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 082e9c0..82b6706 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -240,10 +240,10 @@
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"spela in ljud"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ta bilder och spela in video"</string>
- <string name="permgrouplab_phone" msgid="5229115638567440675">"Mobil"</string>
+ <string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ringa och hantera telefonsamtal"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorer"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"få åtkomst till information om dina vitalparametrar och din fysiska aktivitet"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Kroppssensorer"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"få åtkomst till sensordata om dina vitalparametrar"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Hämta fönsterinnehåll"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Granska innehållet i ett fönster som du interagerar med."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktivera Explore by Touch"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Tillåter att appen tar emot och hanterar MMS-meddelanden. Detta innebär att appen kan övervaka eller ta bort meddelanden som skickats till enheten utan att visa dem för dig."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"läsa SMS-meddelanden"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Appen tillåts läsa SMS som skickas till din enhet. På vissa platser skickas SMS för att varna för nödsituationer. Skadliga appar kan påverka enhetens prestanda eller funktionalitet när du får ett meddelande om en nödsituation via SMS."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Dina konton"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Få åtkomst till tillgängliga konton."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"läsa flöden som du prenumererar på"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Tillåter att appen får information om aktuella synkroniserade flöden."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"skicka och visa sms"</string>
@@ -507,7 +505,7 @@
<string name="policydesc_resetPassword" msgid="1278323891710619128">"Ändra skärmlåset."</string>
<string name="policylab_forceLock" msgid="2274085384704248431">"Lås skärmen"</string>
<string name="policydesc_forceLock" msgid="1141797588403827138">"Kontrollera hur och när skärmlåset aktiveras."</string>
- <string name="policylab_wipeData" msgid="3910545446758639713">"Radera alla data"</string>
+ <string name="policylab_wipeData" msgid="3910545446758639713">"Radera all data"</string>
<string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Ta bort data från surfplattan utan förvarning genom att återställa standardinställningarna."</string>
<string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Rensar uppgifterna på tv:n utan föregående varning genom att återställa standardinställningarna."</string>
<string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Ta bort data från mobilen utan förvarning genom att återställa standardinställningarna."</string>
@@ -630,7 +628,7 @@
<string name="relationTypeMother" msgid="4578571352962758304">"Mamma"</string>
<string name="relationTypeParent" msgid="4755635567562925226">"Förälder"</string>
<string name="relationTypePartner" msgid="7266490285120262781">"Partner"</string>
- <string name="relationTypeReferredBy" msgid="101573059844135524">"Rekommenderad av"</string>
+ <string name="relationTypeReferredBy" msgid="101573059844135524">"Genom"</string>
<string name="relationTypeRelative" msgid="1799819930085610271">"Släkting"</string>
<string name="relationTypeSister" msgid="1735983554479076481">"Syster"</string>
<string name="relationTypeSpouse" msgid="394136939428698117">"Make/maka"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 5b1bd48..fc442f1 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -244,8 +244,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"piga picha na urekodi video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Simu"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"piga na udhibiti simu"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Vihisi"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"fikia maelezo kuhusu alama zako muhimu na shughuli ya kimwili"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Vihisi vya Mwili"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"fikia data ya kihisi kuhusu alama zako muhimu"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Rejesha maudhui ya dirisha"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Chunguza maudhui ya dirisha unaloingiliana nalo."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Washa Chunguza kwa Mguso"</string>
@@ -272,8 +272,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Inaruhusu programu kupokea na kuchakata ujumbe medianwai (MMS). Hii inamaanisha uwezo wa kuchunguza na kufuta ujumbe uliotumwa kwa kifaa chako bila ya kukuonyesha."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"soma mawasiliano ya matangazo ya simu"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Huruhusu programu kusoma mawasiliano ya matangazo ya simu yaliyoingia kwenye kifaa chako. Arifa za matangazo ya simu huwasilishwa katika maeneo mengine ili kukuonya juu ya hali za dharura. Huenda programu hasidi zikatatiza utendajikazi au shughuli ya kifaa chako wakati matangazo ya simu ya dharura yameingia."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Akaunti zako"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Fikia akaunti zinazopatikana."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"kusoma mipasho kutoka vyanzo unavyofuatilia"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Inaruhusu programu kupata maelezo kuhusu mlisho iliyolandanishwa kwa sasa."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"tuma na uangalie ujumbe wa SMS"</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index d1cb5e7..e51677f 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"படங்களை எடுக்கும், வீடியோவைப் பதிவுசெய்யும்"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ஃபோன்"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"மொபைல் அழைப்புகளைச் செய்யும், பெறும்"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"உணர்விகள்"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"உங்கள் உடலியக்க குறிகள் மற்றும் உடல் சார்ந்த செயல்பாடு பற்றிய தகவலை அணுகும்"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"உடல் உணர்விகள்"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"உங்கள் உடலியக்கக் குறிகள் பற்றிய உணர்வித் தரவை அணுகும்"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"சாளர உள்ளடக்கத்தைப் பெறுதல்"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"நீங்கள் ஊடாடிக்கொண்டிருக்கும் சாளரத்தின் உள்ளடக்கத்தைப் பார்க்கலாம்."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"தொடுவதன் மூலம் அறிவதை இயக்கவும்"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMS செய்திகளைப் பெற, செயற்படுத்தப் பயன்பாட்டை அனுமதிக்கிறது. இதற்கு அர்த்தம் உங்கள் சாதனத்திற்கு அனுப்பப்படும் செய்திகளை உங்களுக்குக் காட்டாமல் கண்காணிக்கவோ, நீக்கவோ பயன்பாட்டால் முடியும் என்பதாகும்."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"செல் அலைபரப்புச் செய்திகளைப் படித்தல்"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"உங்கள் சாதனத்தில் பெறப்படும் செல் அலைபரப்புச் செய்திகளைப் படிப்பதற்குப் பயன்பாட்டை அனுமதிக்கிறது. அவசரநிலை சூழ்நிலைகளை உங்களுக்கு எச்சரிக்கைச் செய்வதற்கு சில இடங்களில் செல் அலைபரப்பு விழிப்பூட்டல்கள் வழங்கப்படும். அவசரநிலை மொபைல் அலைபரப்புப் பெறப்படும்போது உங்கள் சாதனத்தின் செயல்திறன் அல்லது செயல்பாட்டுடன் தீங்கிழைக்கும் பயன்பாடுகள் அதைத் தடுக்கலாம்."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"உங்கள் கணக்குகள்"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"கிடைக்கும் கணக்குகளை அணுக முடியும்."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"குழுசேர்ந்த ஊட்டங்களைப் படித்தல்"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"தற்போது ஒத்திசைந்த ஊட்டங்களைப் பற்றிய விவரங்களைப் பெற பயன்பாட்டை அனுமதிக்கிறது."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS செய்திகளை அனுப்புதல் மற்றும் பார்த்தல்"</string>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 364e21c..a7656b4 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"చిత్రాలను తీస్తుంది మరియు వీడియోను రికార్డ్ చేస్తుంది"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ఫోన్"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ఫోన్ కాల్‌లను చేస్తుంది మరియు నిర్వహిస్తుంది"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"సెన్సార్‌లు"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"మీ అత్యంత కీలకమైన గుర్తులు మరియు భౌతిక కార్యాచరణ గురించి సమాచారాన్ని ప్రాప్యత చేస్తుంది"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"శరీర సెన్సార్‌లు"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"మీ అత్యంత కీలకమైన గుర్తుల గురించి సెన్సార్ డేటాని ప్రాప్యత చేస్తుంది"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"విండో కంటెంట్‍ను తిరిగి పొందుతుంది"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"మీరు పరస్పర చర్య చేస్తున్న విండో కంటెంట్‌‍ను పరిశీలించండి."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"తాకడం ద్వారా విశ్లేషణను ప్రారంభిస్తుంది"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMS సందేశాలను స్వీకరించడానికి మరియు ప్రాసెస్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. అనువర్తనం మీ పరికరానికి పంపబడిన సందేశాలను మీకు చూపకుండానే పర్యవేక్షించగలదని లేదా తొలగించగలదని దీని అర్థం."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"సెల్ ప్రసార సందేశాలను చదవడం"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"మీ పరికరం స్వీకరించిన సెల్ ప్రసార సందేశాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. సెల్ ప్రసార హెచ్చరికలు అత్యవసర పరిస్థితుల గురించి మిమ్మల్ని హెచ్చరించడానికి కొన్ని స్థానాల్లో అందించబడతాయి. అత్యవసర సెల్ ప్రసారం స్వీకరించినప్పుడు హానికరమైన అనువర్తనాలు మీ పరికరం యొక్క పనితీరు లేదా నిర్వహణకు అంతరాయం కలిగించవచ్చు."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"మీ ఖాతాలు"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"అందుబాటులో ఉన్న ఖాతాలను ప్రాప్యత చేయండి."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"చందా చేయబడిన ఫీడ్‌లను చదవడం"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ప్రస్తుతం సమకాలీకరించిన ఫీడ్‌ల గురించి వివరాలను పొందడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS సందేశాలను పంపడానికి మరియు వీక్షించడానికి అనుమతి"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 147763e..229a2b8 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ถ่ายภาพและบันทึกวิดีโอ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"โทรศัพท์"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"โทรและจัดการการโทร"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"เซ็นเซอร์"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"เข้าถึงข้อมูลเกี่ยวกับสัญญาณชีพและกิจกรรมทางกายภาพ"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"เซ็นเซอร์สำหรับร่างกาย"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"เข้าถึงข้อมูลเซ็นเซอร์เกี่ยวกับสัญญาณชีพของคุณ"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"เรียกข้อมูลเนื้อหาของหน้าต่าง"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ตรวจสอบเนื้อหาของหน้าต่างที่คุณกำลังโต้ตอบอยู่"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"เปิด \"แตะเพื่อสำรวจ\""</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"อนุญาตให้แอปพลิเคชันรับและประมวลผลข้อความ MMS ซึ่งหมายความว่าแอปพลิเคชันจะสามารถตรวจสอบหรือลบข้อความที่ส่งมายังอุปกรณ์ของคุณได้โดยไม่ต้องแสดงให้คุณเห็น"</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"อ่านข้อความที่ได้รับจากสถานีมือถือ"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"อนุญาตให้แอปอ่านข้อความจากสถานีมือถือที่อุปกรณ์ได้รับ การแจ้งเตือนทางมือถือมีให้บริการในบางพื้นที่ โดยจะแจ้งเตือนคุณเกี่ยวกับสถานการณ์ฉุกเฉิน แอปที่เป็นอันตรายอาจเข้าแทรกแซงการทำงานของอุปกรณ์เมื่อได้รับข้อความแจ้งเตือนฉุกเฉิน"</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"บัญชีของคุณ"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"เข้าถึงบัญชีที่ใช้งานได้"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"อ่านฟีดข้อมูลที่สมัครไว้"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"อนุญาตให้แอปพลิเคชันดูรายละเอียดเกี่ยวกับฟีดที่ซิงค์ไว้ในปัจจุบัน"</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"ส่งและดูข้อความ SMS"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 152e9e4..2feab88 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"kumukuha ng mga larawan at nagre-record ng video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telepono"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"tumatawag sa telepono at namamahala sa mga tawag sa telepono"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Mga Sensor"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"i-access ang impormasyon tungkol sa iyong mahahalagang senyales at pisikal na aktibidad"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Mga Sensor ng Katawan"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"i-access ang data ng sensor tungkol sa iyong mahahalagang senyales"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Kunin ang content ng window"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Siyasatin ang nilalaman ng isang window kung saan ka nakikipag-ugnayan."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"I-on ang Explore by Touch"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Pinapayagan ang app na tumanggap at magproseso ng mga mensaheng MMS. Nangangahulugan ito na maaaring sumubaybay o magtanggal ang app ng mga mensaheng ipinapadala sa iyong device nang hindi ipinapakita ang mga ito sa iyo."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"basahin ang mga mensahe ng cell broadcast"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Binibigyang-daan ang app na magbasa ng mga mensahe ng cell broadcast na natanggap ng iyong device. Inihahatid ang mga alerto ng cell broadcast sa ilang lokasyon upang balaan ka tungkol sa mga emergency na sitwasyon. Maaaring makaabala ang nakakahamak na apps sa pagganap o pagpapatakbo ng iyong device kapag nakatanggap ng emergency na cell broadcast."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Iyong mga account"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"I-access ang mga available na account."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"magbasa ng mga na-subscribe na feed"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Pinapayagan ang app na kumuha ng mga detalye tungkol sa kasalukuyang naka-sync na mga feed."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"magpadala at tumingin ng mga mensaheng SMS"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index d9c587c..bc13b1f 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"fotoğraf çekme ve video kaydetme"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"telefon aramaları yapma ve çağrıları yönetme"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensörler"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"hayati belirtileriniz ve fiziksel aktivitenizle ilgili bilgilere erişme"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Vücut Sensörleri"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"hayati belirtilerinizle ilgili sensör verilerine erişme"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pencere içeriğini alma"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Etkileşim kurduğunuz pencerenin içeriğini inceler."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Dokunarak Keşfet\'i açma"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Uygulamaya MMS iletilerini alma ve işleme izni verir. Bu izin, uygulamanın cihazınıza gönderilen iletileri takip edip size göstermeden silebileceği anlamına gelir."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"hücre yayını mesajlarını oku"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Uygulamaya, cihazınız tarafından alınan hücre yayını mesajlarını okuma izni verir. Hücre yayını uyarıları bazı yerlerde acil durumlar konusunda sizi uyarmak için gönderilir. Kötü amaçlı uygulamalar acil hücre yayını alındığında cihazınızın performansına ya da çalışmasına engel olabilir."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Hesaplarınız"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Kullanılabilir hesaplara erişin."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"abone olunan yayınları okuma"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Uygulamaya, o anda senkronize olan özet akışları ile ilgili bilgi alma izni verir."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS iletileri gönderme ve görüntüleme"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 5545d46..338db0f 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -244,8 +244,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"фотографувати та записувати відео"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"телефонувати та керувати дзвінками"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Датчики"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"отримувати доступ до інформації про ваші життєві показники та фізичну активність"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Датчики на тілі"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"отримувати доступ до інформації датчиків про ваші життєві показники"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Отримувати вміст вікна"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Перевіряти вміст вікна, з яким ви взаємодієте."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Увімкнути функцію дослідження дотиком"</string>
@@ -272,8 +272,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Дозволяє програмі отримувати й обробляти MMS-повідомлення. Це означає, що програма може відстежувати чи видаляти повідомлення, надіслані на ваш пристрій, навіть не показуючи їх вам."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"читати широкомовні повідомлення мережі"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Дозволяє програмі читати широкомовні повідомлення мережі, отримані пристроєм. Широкомовні сповіщення мережі надсилаються в деяких країнах для попередження про надзвичайні ситуації. Шкідливі програми можуть втручатися у швидкодію чи роботу пристрою під час отримання широкомовного повідомлення мережі про надзвичайну ситуацію."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Ваші облікові записи"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Доступ до доступних обл. записів."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"читати підписані канали"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Дозволяє програмі отримувати відомості про поточно синхронізовані канали."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"надсилати та переглядати SMS-повідомлення"</string>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 7d94b64..7890c2a 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -242,16 +242,16 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"تصاویر لیں اور ویڈیو ریکارڈ کریں"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"فون"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"فون کالز کریں اور ان کا نظم کریں"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"سینسرز"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"اپنی علاماتِ حیات اور جسمانی سرگرمی بارے معلومات تک رسائی حاصل کریں"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"جسم سینسرز"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"اپنی علامات حیات کے متعلق سنسر ڈیٹا تک رسائی حاصل کریں"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ونڈو مواد بازیافت کرنے کی"</string>
- <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"کسی ایسے ونڈو کے مواد کا معائنہ کریں جس کے ساتھ آپ تعامل کر رہے ہیں۔"</string>
+ <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"کسی ایسی ونڈو کے مواد کا معائنہ کریں جس کے ساتھ آپ تعامل کر رہے ہیں۔"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ٹچ کے ذریعے دریافت کریں کو آن کریں"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"ٹچ کیے ہوئے آئٹمز کو زور سے بولا جائے گا اور اشاروں کا استعمال کرکے اسکرین کو دریافت کیا جا سکتا ہے۔"</string>
<string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"‏بہتر ویب accessibility کو آن کریں"</string>
<string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"ایپ کا مواد مزید قابل رسائی بنانے کیلئے اسکرپٹس کو انسٹال کیا جا سکتا ہے۔"</string>
<string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"آپکے ٹائپ کردہ متن کا مشاہدہ کرنے کی"</string>
- <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"کریڈٹ کارڈ نمبرز اور پاس ورڈز جیسے ذاتی ڈیٹا پر مشتمل ہوتا ہے۔"</string>
+ <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"اس میں ذاتی ڈیٹا جیسے کریڈٹ کارڈ نمبرز اور پاس ورڈز شامل ہیں۔"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"اسٹیٹس بار کو غیر فعال یا اس میں ترمیم کریں"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"ایپ کو اسٹیٹس بار غیر فعال کرنے یا سسٹم آئیکنز شامل کرنے اور ہٹانے کی اجازت دیتا ہے۔"</string>
<string name="permlab_statusBarService" msgid="7247281911387931485">"حیثیت بار"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"‏ایپ کو MMS پیغامات حاصل اور ان پر کارروائی کرنے کی اجازت دیتا ہے۔ اس کا مطلب ہے کہ ایپ آپ کے آلے پر مرسلہ پیغامات آپ کو دکھائے بغیر ان پر نگاہ رکھ یا انہیں حذف کرسکتی ہے۔"</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"سیل کے نشریاتی پیغامات پڑھیں"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ایپ کو آپ کے آلے کو موصولہ سیل کے نشریاتی پیغامات پڑھنے کی اجازت دیتا ہے۔ سیل کی نشریاتی الرٹس آپ کو ہنگامی حالات سے مطلع کرنے کیلئے کچھ مقامات میں مہیا کی جاتی ہیں۔ نقصان دہ ایپس کوئی ہنگامی سیل کا نشریہ موصول ہونے پر آپ کے آلے کی کارکردگی یا عمل میں خلل ڈال سکتی ہیں۔"</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"آپ کے اکاؤنٹس"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"دستیاب اکاؤنٹس تک رسائی حاصل کریں۔"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"سبسکرائب کردہ فیڈز پڑھیں"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ایپ کو فی الحال مطابقت پذیر کیے ہوئے فیڈز کے بارے میں تفصیلات حاصل کرنے کی اجازت دیتا ہے۔"</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"‏SMS پیغامات بھیجیں اور دیکھیں"</string>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 875e350..38a5ef1 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"rasm va videoga olish"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"telefon qo‘ng‘iroqlarini amalga oshirish va boshqarish"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorlar"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"asosiy belgilaringiz va jismoniy faolligingiz haqidagi ma’lumotlarga kirish"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Tana sezgichlari"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"asosiy belgilaringiz haqidagi sezgich ma’lumotlariga kirish"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Oynadagi kontentni o‘qiydi"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Joriy oynadagi kontent mazmunini aniqlaydi."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Tegib o‘rganish xizmatini yoqish"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Ilovaga MMS xabarlarini qabul qilish va ularni qayta ishlash uchun ruxsat beradi. Bu sizga yuborilgan xabarlarni ilova sizga ko‘rsatmasdan kuzatishi va o‘chirishi mumkinligini bildiradi."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"uyali tarmoq operatori xabarlarini o‘qish"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Ilovaga qurilmangiz tomonidan qabul qilingan uyali tarmoq operatori xabarlarini o‘qish uchun ruxsat beradi. Uyali tarmoq operatorining ogohlantiruvchi xabarlari ba’zi manzillarga favqulodda holatlar haqida ogohlantirish uchun jo‘natiladi. Zararli ilovalar uyali tarmoq orqali favqulodda xabar qabul qilinganda qurilmangizning ish faoliyati yoki amallariga xalaqit qilishi mumkin"</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Hisoblaringiz"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Mavjud hisoblarga kirish."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"obunalarni o‘qish"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Ilova hozirgi vaqtda sinxronlanayotgan elementlar to‘g‘risidagi ma’lumotlarni olishi mumkin."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS xabarlarni yuborish va ko‘rish"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index b3d9ac5..1ffffed 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"chụp ảnh và quay video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Điện thoại"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"thực hiện và quản lý cuộc gọi điện thoại"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Cảm biến"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"truy cập thông tin về các dấu hiệu quan trọng và hoạt động thể chất của bạn"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Cảm biến cơ thể"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"truy cập dữ liệu cảm biến về dấu hiệu sinh tồn của bạn"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Truy xuất nội dung cửa sổ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Kiểm tra nội dung của cửa sổ bạn đang tương tác."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Bật Khám phá bằng cách chạm"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Cho phép ứng dụng nhận và xử lý tin nhắn MMS. Điều này có nghĩa là ứng dụng có thể theo dõi hoặc xóa tin nhắn được gửi đến thiết bị của bạn mà không hiển thị chúng cho bạn."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"đọc tin nhắn quảng bá"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Cho phép ứng dụng đọc tin nhắn quảng bá mà thiết bị của bạn nhận được. Tin nhắn quảng bá cảnh báo được gửi ở một số địa điểm nhằm cảnh báo cho bạn về các tình huống khẩn cấp. Các ứng dụng độc hại có thể gây ảnh hưởng đến hiệu suất hoặc hoạt động của thiết bị của bạn khi nhận được tin nhắn quảng bá khẩn cấp."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Tài khoản của bạn"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Truy cập các tài khoản khả dụng."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"đọc nguồn cấp dữ liệu đã đăng ký"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Cho phép ứng dụng lấy thông tin chi tiết về nguồn cấp dữ liệu hiện được đồng bộ hóa."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"gửi và xem tin nhắn SMS"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 0eb949d..aa45b13 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"拍摄照片和录制视频"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"电话"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"拨打电话和管理通话"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"传感器"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"访问与您的生命体征和健身运动相关的信息"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"身体传感器"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"访问与您的生命体征相关的传感器数据"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"检索窗口内容"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"检查您正与其进行互动的窗口的内容。"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"启用触摸浏览"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"允许该应用接收和处理彩信。这就意味着,该应用可能会监视发送到您设备的彩信,或删除发送到您设备的彩信而不向您显示。"</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"读取小区广播消息"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"允许应用读取您的设备收到的小区广播消息。小区广播消息是在某些地区发送的、用于发布紧急情况警告的提醒信息。恶意应用可能会在您收到小区紧急广播时干扰您设备的性能或操作。"</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"您的帐户"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"访问可用的帐户。"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"读取订阅的供稿"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"允许应用获取有关当前同步的 Feed 的详情。"</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"发送和查看短信"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 7043399..11ac6d9 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"拍照和錄製影片"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"電話"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"撥打電話及管理通話"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"感應器"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"存取與您的生命體徵和身體活動相關的資料"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"人體感應器"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"存取與您生命體徵相關的感應器資料"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"擷取視窗內容"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"檢查您使用中的視窗內容。"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"開啟「輕觸探索」功能"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"允許應用程式接收和處理 MMS 訊息。這表示應用程式可監控傳送至您裝置的訊息,或在您閱讀訊息前擅自刪除訊息。"</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"讀取區域廣播訊息"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"允許應用程式讀取您裝置接收的區域廣播訊息。某些地點會發出區域廣播警報,警告您發生緊急狀況。惡意應用程式可能會在裝置收到緊急區域廣播時,干擾裝置的性能或運作。"</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"您的帳戶"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"存取可用帳戶。"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"讀取訂閱的資訊提供"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"允許應用程式取得目前已同步的資訊提供的詳細資料。"</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"傳送和查看 SMS 短訊"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index f3a4aec..4d1b944 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"拍照及錄製影片"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"電話"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"撥打電話及管理通話"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"感應器"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"存取生命徵象和體能活動的相關資訊"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"身體感應器"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"存取生命徵象相關感應器資料"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"擷取視窗內容"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"檢查您存取的視窗內容。"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"啟用輕觸探索功能"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"允許應用程式接收和處理多媒體訊息。這項設定可讓應用程式監控傳送至您裝置的訊息,或在您閱讀訊息前擅自刪除訊息。"</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"讀取區域廣播訊息"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"允許應用程式讀取您裝置收到的區域廣播訊息。某些地點會發出區域廣播警示,警告您有緊急狀況發生。請注意,惡意應用程式可能會在裝置收到緊急區域廣播時,干擾裝置的效能或運作。"</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"您的帳戶"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"存取可用帳戶。"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"讀取訂閱資訊提供"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"允許應用程式取得目前已同步處理的資訊提供詳細資料。"</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"傳送及查看簡訊"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index afb1fbd..1129d9a 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -242,8 +242,8 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"thatha izithombe uphinde urekhode ividiyo"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Ifoni"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"yenza uphinde uphathe amakholi wefoni"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Izinzwa"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"finyelela kulwazi olumayelana nezimpawu zakho zempilo nomsebenzi womzimba"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Izinzwa zomzimba"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"finyelela idatha yesizweli mayelana nezimpawu zakho ezibalulekile"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Thola okuqukethwe kwewindi"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Hlola okuqukethwe kwewindi ohlanganyela nalo."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Vula ukuhlola ngokuthinta"</string>
@@ -270,8 +270,6 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Ivumela uhlelo lokusebenza ukuthola nokucubungula imilayezo ye-MMS. Loku kuchaza ukuthi uhlelo lokusebenza lungangamela noma lesuse imilayezo ethunyelwe kudivayisi yakho ngaphandle kokukubonisa yona."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"funda imilayezo yokusakaza yeselula"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Ivumela uhlelo lokusebenza ukufunda imilayezo yokusakaza yeselula etholwe idivayisi yakho. Izaziso zokusakaza zeselula zilethwa kwezinye izindawo ukukuxwayisa ngezimo ezisheshayo. Izinhlelo zokusebenza ezingalungile zingaphazamisana nokusebenza noma umsebenzi wedivayisi yakho uma ukusakaza kweselula kwesimo esisheshayo kutholwa."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Ama-akhawunti akho"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Finyelela kuma-akhawunti atholakalayo"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"funda izifunzo ezikhokhelwayo"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Ivumela uhlelo lokusebenza ukuthi ithole imininingwane mayelana namafidi avumelnisiwe njengamanje."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"thumela uphinde ubuke imilayezo ye-SMS"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 33c9c60..b1925ba 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -27,6 +27,9 @@
<!-- ============== -->
<eat-comment />
+ <!-- Specifies that a theme has a light background with dark text on top. -->
+ <attr name="isLightTheme" format="boolean" />
+
<!-- Default color of foreground imagery. -->
<attr name="colorForeground" format="color" />
<!-- Default color of foreground imagery on an inverted background. -->
@@ -3121,6 +3124,8 @@ i
<flag name="typeWindowsChanged" value="0x00400000" />
<!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CONTEXT_CLICKED} events. -->
<flag name="typeContextClicked" value="0x00800000" />
+ <!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_ASSIST_READING_CONTEXT} events. -->
+ <flag name="typeAssistReadingContext" value="0x01000000" />
<!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPES_ALL_MASK} i.e. all events. -->
<flag name="typeAllMask" value="0xffffffff" />
</attr>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 3cb4d7c..70f9db9 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -215,6 +215,11 @@
<!-- Additional flag from base permission type: this permission is closely
associated with an app op for controlling access. -->
<flag name="appop" value="0x40" />
+ <!-- Additional flag from base permission type: this permission can be automatically
+ granted to apps that target API levels below
+ {@link android.os.Build.VERSION_CODES#MNC} (before runtime permissions
+ were introduced). -->
+ <flag name="pre23" value="0x80" />
</attr>
<!-- Flags indicating more context for a permission group. -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index f6cefba..451813c 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1268,6 +1268,14 @@
application is desired. -->
<string name="default_sms_application" translatable="false">com.android.mms</string>
+ <!-- Default web browser. This is the package name of the application that will
+ be the default browser when the device first boots. Afterwards the user
+ can select whatever browser app they wish to use as the default.
+
+ If this string is empty or the specified package does not exist, then
+ the behavior will be as though no app was named as an explicit default. -->
+ <string name="default_browser" translatable="false"></string>
+
<!-- Enable/disable default bluetooth profiles:
HSP_AG, ObexObjectPush, Audio, NAP -->
<bool name="config_bluetooth_default_profiles">true</bool>
@@ -2248,4 +2256,9 @@
(range of 18 - 21 kHz). -->
<bool name="config_supportSpeakerNearUltrasound">true</bool>
+ <!-- Flag indicating device support for EAP SIM, AKA, AKA' -->
+ <bool name="config_eap_sim_based_auth_supported">true</bool>
+
+ <!-- How long history of previous vibrations should be kept for the dumpsys. -->
+ <integer name="config_previousVibrationsDumpLimit">20</integer>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 5c974bd..680a1ab 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -584,7 +584,7 @@
<string name="permgroupdesc_phone">make and manage phone calls</string>
<!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permgrouplab_sensors">Sensors</string>
+ <string name="permgrouplab_sensors">Body Sensors</string>
<!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permgroupdesc_sensors">access sensor data about your vital signs</string>
@@ -676,11 +676,6 @@
Malicious apps may interfere with the performance or operation of your
device when an emergency cell broadcast is received.</string>
- <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permgrouplab_accounts">Your accounts</string>
- <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permgroupdesc_accounts">Access the available accounts.</string>
-
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_subscribedFeedsRead">read subscribed feeds</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -2891,19 +2886,6 @@
<!-- See USB_PREFERENCES. This is the message. -->
<string name="usb_notification_message">Touch for more options.</string>
- <!-- External media format dialog strings -->
- <!-- This is the label for the activity, and should never be visible to the user. -->
- <!-- See EXTMEDIA_FORMAT. EXTMEDIA_FORMAT_DIALOG: After the user selects the notification, a dialog is shown asking if he wants to format the SD card. This is the title. [CHAR LIMIT=20] -->
- <string name="extmedia_format_title" product="nosdcard">Format USB storage?</string>
- <!-- See EXTMEDIA_FORMAT. EXTMEDIA_FORMAT_DIALOG: After the user selects the notification, a dialog is shown asking if he wants to format the SD card. This is the title. -->
- <string name="extmedia_format_title" product="default">Format SD card?</string>
- <!-- See EXTMEDIA_FORMAT. This is the message. [CHAR LIMIT=NONE] -->
- <string name="extmedia_format_message" product="nosdcard">All files stored in your USB storage will be erased. This action can\'t be reversed!</string>
- <!-- See EXTMEDIA_FORMAT. This is the message. -->
- <string name="extmedia_format_message" product="default">All data on your card will be lost.</string>
- <!-- See EXTMEDIA_FORMAT. This is the button text to format the sd card. -->
- <string name="extmedia_format_button_format">Format</string>
-
<!-- Title of notification shown when ADB is actively connected to the phone. -->
<string name="adb_active_notification_title">USB debugging connected</string>
<!-- Message of notification shown when ADB is actively connected to the phone. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3a1a156..5de010d 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -240,6 +240,7 @@
<java-symbol type="attr" name="windowFixedHeightMajor" />
<java-symbol type="attr" name="windowFixedHeightMinor" />
<java-symbol type="attr" name="accessibilityFocusedDrawable"/>
+ <java-symbol type="attr" name="isLightTheme"/>
<java-symbol type="bool" name="action_bar_embed_tabs" />
<java-symbol type="bool" name="action_bar_embed_tabs_pre_jb" />
@@ -624,9 +625,6 @@
<java-symbol type="string" name="eventTypeBirthday" />
<java-symbol type="string" name="eventTypeCustom" />
<java-symbol type="string" name="eventTypeOther" />
- <java-symbol type="string" name="extmedia_format_button_format" />
- <java-symbol type="string" name="extmedia_format_message" />
- <java-symbol type="string" name="extmedia_format_title" />
<java-symbol type="string" name="fileSizeSuffix" />
<java-symbol type="string" name="force_close" />
<java-symbol type="string" name="format_error" />
@@ -902,6 +900,7 @@
<java-symbol type="string" name="sipAddressTypeOther" />
<java-symbol type="string" name="sipAddressTypeWork" />
<java-symbol type="string" name="default_sms_application" />
+ <java-symbol type="string" name="default_browser" />
<java-symbol type="string" name="sms_control_message" />
<java-symbol type="string" name="sms_control_title" />
<java-symbol type="string" name="sms_control_no" />
@@ -1706,6 +1705,7 @@
<java-symbol type="integer" name="config_notificationsBatteryLowARGB" />
<java-symbol type="integer" name="config_notificationsBatteryMediumARGB" />
<java-symbol type="integer" name="config_notificationServiceArchiveSize" />
+ <java-symbol type="integer" name="config_previousVibrationsDumpLimit" />
<java-symbol type="integer" name="config_radioScanningTimeout" />
<java-symbol type="integer" name="config_screenBrightnessSettingMinimum" />
<java-symbol type="integer" name="config_screenBrightnessSettingMaximum" />
@@ -2318,5 +2318,5 @@
<java-symbol type="drawable" name="ic_dialog_alert_material" />
<java-symbol type="bool" name="allow_stacked_button_bar" />
-
+ <java-symbol type="bool" name="config_eap_sim_based_auth_supported" />
</resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index b7acdd4..c230645 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -42,6 +42,7 @@ please see themes_device_defaults.xml.
-->
<style name="Theme">
+ <item name="isLightTheme">false</item>
<item name="colorForeground">@color/bright_foreground_dark</item>
<item name="colorForegroundInverse">@color/bright_foreground_dark_inverse</item>
<item name="colorBackground">@color/background_dark</item>
@@ -472,6 +473,7 @@ please see themes_device_defaults.xml.
background will be a light color.
<p>This is designed for API level 10 and lower.</p>-->
<style name="Theme.Light">
+ <item name="isLightTheme">true</item>
<item name="windowBackground">@drawable/screen_background_selector_light</item>
<item name="windowClipToOutline">false</item>
diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk b/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk
index 6ee6ffa..6b3b55e 100644
--- a/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk
+++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk
@@ -5,6 +5,4 @@ LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := install_jni_lib_open_from_apk
-LOCAL_PAGE_ALIGN_JNI_SHARED_LIBRARIES := true
-
include $(FrameworkCoreTests_BUILD_PACKAGE)
diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
index 5c55efb..ea444a4 100644
--- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java
+++ b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
@@ -16,6 +16,8 @@
package android.net;
+import android.net.IpPrefix;
+import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.LinkProperties.ProvisioningChange;
import android.net.RouteInfo;
@@ -26,6 +28,7 @@ import junit.framework.TestCase;
import java.net.InetAddress;
import java.util.ArrayList;
+
public class LinkPropertiesTest extends TestCase {
private static InetAddress ADDRV4 = NetworkUtils.numericToInetAddress("75.208.6.1");
private static InetAddress ADDRV6 = NetworkUtils.numericToInetAddress(
@@ -567,4 +570,80 @@ public class LinkPropertiesTest extends TestCase {
assertEquals(ProvisioningChange.STILL_PROVISIONED,
LinkProperties.compareProvisioning(v6lp, v6lp2));
}
+
+ @SmallTest
+ public void testIsReachable() {
+ final LinkProperties v4lp = new LinkProperties();
+ assertFalse(v4lp.isReachable(DNS1));
+ assertFalse(v4lp.isReachable(DNS2));
+
+ // Add an on-link route, making the on-link DNS server reachable,
+ // but there is still no IPv4 address.
+ assertTrue(v4lp.addRoute(new RouteInfo(
+ new IpPrefix(NetworkUtils.numericToInetAddress("75.208.0.0"), 16))));
+ assertFalse(v4lp.isReachable(DNS1));
+ assertFalse(v4lp.isReachable(DNS2));
+
+ // Adding an IPv4 address (right now, any IPv4 address) means we use
+ // the routes to compute likely reachability.
+ assertTrue(v4lp.addLinkAddress(new LinkAddress(ADDRV4, 16)));
+ assertTrue(v4lp.isReachable(DNS1));
+ assertFalse(v4lp.isReachable(DNS2));
+
+ // Adding a default route makes the off-link DNS server reachable.
+ assertTrue(v4lp.addRoute(new RouteInfo(GATEWAY1)));
+ assertTrue(v4lp.isReachable(DNS1));
+ assertTrue(v4lp.isReachable(DNS2));
+
+ final LinkProperties v6lp = new LinkProperties();
+ final InetAddress kLinkLocalDns = NetworkUtils.numericToInetAddress("fe80::6:1");
+ final InetAddress kLinkLocalDnsWithScope = NetworkUtils.numericToInetAddress("fe80::6:2%43");
+ final InetAddress kOnLinkDns = NetworkUtils.numericToInetAddress("2001:db8:85a3::53");
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertFalse(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertFalse(v6lp.isReachable(kOnLinkDns));
+ assertFalse(v6lp.isReachable(DNS6));
+
+ // Add a link-local route, making the link-local DNS servers reachable. Because
+ // we assume the presence of an IPv6 link-local address, link-local DNS servers
+ // are considered reachable, but only those with a non-zero scope identifier.
+ assertTrue(v6lp.addRoute(new RouteInfo(
+ new IpPrefix(NetworkUtils.numericToInetAddress("fe80::"), 64))));
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertFalse(v6lp.isReachable(kOnLinkDns));
+ assertFalse(v6lp.isReachable(DNS6));
+
+ // Add a link-local address--nothing changes.
+ assertTrue(v6lp.addLinkAddress(LINKADDRV6LINKLOCAL));
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertFalse(v6lp.isReachable(kOnLinkDns));
+ assertFalse(v6lp.isReachable(DNS6));
+
+ // Add a global route on link, but no global address yet. DNS servers reachable
+ // via a route that doesn't require a gateway: give them the benefit of the
+ // doubt and hope the link-local source address suffices for communication.
+ assertTrue(v6lp.addRoute(new RouteInfo(
+ new IpPrefix(NetworkUtils.numericToInetAddress("2001:db8:85a3::"), 64))));
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertTrue(v6lp.isReachable(kOnLinkDns));
+ assertFalse(v6lp.isReachable(DNS6));
+
+ // Add a global address; the on-link global address DNS server is (still)
+ // presumed reachable.
+ assertTrue(v6lp.addLinkAddress(new LinkAddress(ADDRV6, 64)));
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertTrue(v6lp.isReachable(kOnLinkDns));
+ assertFalse(v6lp.isReachable(DNS6));
+
+ // Adding a default route makes the off-link DNS server reachable.
+ assertTrue(v6lp.addRoute(new RouteInfo(GATEWAY62)));
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertTrue(v6lp.isReachable(kOnLinkDns));
+ assertTrue(v6lp.isReachable(DNS6));
+ }
}
diff --git a/core/tests/coretests/src/android/text/format/FormatterTest.java b/core/tests/coretests/src/android/text/format/FormatterTest.java
new file mode 100644
index 0000000..d2e2131
--- /dev/null
+++ b/core/tests/coretests/src/android/text/format/FormatterTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.format;
+
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.format.Formatter.BytesResult;
+
+import java.util.Locale;
+
+public class FormatterTest extends AndroidTestCase {
+
+ private Locale mOriginalLocale;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mOriginalLocale = mContext.getResources().getConfiguration().locale;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (mOriginalLocale != null) {
+ setLocale(mOriginalLocale);
+ }
+ super.tearDown();
+ }
+
+ private void setLocale(Locale locale) {
+ Resources res = getContext().getResources();
+ Configuration config = res.getConfiguration();
+ config.locale = locale;
+ res.updateConfiguration(config, res.getDisplayMetrics());
+
+ Locale.setDefault(locale);
+ }
+
+ @SmallTest
+ public void testFormatBytes() {
+ setLocale(Locale.ENGLISH);
+
+ checkFormatBytes(0, true, "0.00", 0);
+ checkFormatBytes(0, false, "0.00", 0);
+
+ checkFormatBytes(1, true, "1.0", 1);
+ checkFormatBytes(1, false, "1.00", 1);
+
+ checkFormatBytes(12, true, "12", 12);
+ checkFormatBytes(12, false, "12.00", 12);
+
+ checkFormatBytes(123, true, "123", 123);
+ checkFormatBytes(123, false, "123", 123);
+
+ checkFormatBytes(812, true, "812", 812);
+ checkFormatBytes(812, false, "812", 812);
+
+ checkFormatBytes(912, true, "0.89", 911);
+ checkFormatBytes(912, false, "0.89", 911);
+
+ checkFormatBytes(9123, true, "8.9", 9113);
+ checkFormatBytes(9123, false, "8.91", 9123);
+
+ checkFormatBytes(9123000, true, "8.7", 9122611);
+ checkFormatBytes(9123000, false, "8.70", 9122611);
+
+ // The method doesn't really support negative values, but apparently people pass -1...
+ checkFormatBytes(-1, true, "-1.00", -1);
+ checkFormatBytes(-1, false, "-1.00", -1);
+
+ // Missing FLAG_CALCULATE_ROUNDED case.
+ BytesResult r = Formatter.formatBytes(getContext().getResources(), 1, 0);
+ assertEquals("1.00", r.value);
+ assertEquals(0, r.roundedBytes); // Didn't pass FLAG_CALCULATE_ROUNDED
+
+ // Make sure it works on different locales.
+ setLocale(new Locale("es", "ES"));
+ checkFormatBytes(9123000, false, "8,70", 9122611);
+ }
+
+ private void checkFormatBytes(long bytes, boolean useShort,
+ String expectedString, long expectedRounded) {
+ BytesResult r = Formatter.formatBytes(getContext().getResources(), bytes,
+ Formatter.FLAG_CALCULATE_ROUNDED | (useShort ? Formatter.FLAG_SHORTER : 0));
+ assertEquals(expectedString, r.value);
+ assertEquals(expectedRounded, r.roundedBytes);
+ }
+}
diff --git a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
index a50fb54..31a4703 100644
--- a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
+++ b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
@@ -51,11 +51,15 @@ public class InputMethodTest extends InstrumentationTestCase {
private static final Locale LOCALE_FR = new Locale("fr");
private static final Locale LOCALE_FR_CA = new Locale("fr", "CA");
private static final Locale LOCALE_HI = new Locale("hi");
+ private static final Locale LOCALE_JA = new Locale("ja");
private static final Locale LOCALE_JA_JP = new Locale("ja", "JP");
private static final Locale LOCALE_ZH_CN = new Locale("zh", "CN");
private static final Locale LOCALE_ZH_TW = new Locale("zh", "TW");
private static final Locale LOCALE_IN = new Locale("in");
private static final Locale LOCALE_ID = new Locale("id");
+ private static final Locale LOCALE_TH = new Locale("ht");
+ private static final Locale LOCALE_TH_TH = new Locale("ht", "TH");
+ private static final Locale LOCALE_TH_TH_TH = new Locale("ht", "TH", "TH");
private static final String SUBTYPE_MODE_KEYBOARD = "keyboard";
private static final String SUBTYPE_MODE_VOICE = "voice";
private static final String SUBTYPE_MODE_ANY = null;
@@ -849,4 +853,99 @@ public class InputMethodTest extends InstrumentationTestCase {
return preinstalledImes;
}
+
+ @SmallTest
+ public void testGetSuitableLocalesForSpellChecker() throws Exception {
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_US);
+ assertEquals(3, locales.size());
+ assertEquals(LOCALE_EN_US, locales.get(0));
+ assertEquals(LOCALE_EN_GB, locales.get(1));
+ assertEquals(LOCALE_EN, locales.get(2));
+ }
+
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_GB);
+ assertEquals(3, locales.size());
+ assertEquals(LOCALE_EN_GB, locales.get(0));
+ assertEquals(LOCALE_EN_US, locales.get(1));
+ assertEquals(LOCALE_EN, locales.get(2));
+ }
+
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN);
+ assertEquals(3, locales.size());
+ assertEquals(LOCALE_EN, locales.get(0));
+ assertEquals(LOCALE_EN_US, locales.get(1));
+ assertEquals(LOCALE_EN_GB, locales.get(2));
+ }
+
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_IN);
+ assertEquals(4, locales.size());
+ assertEquals(LOCALE_EN_IN, locales.get(0));
+ assertEquals(LOCALE_EN_US, locales.get(1));
+ assertEquals(LOCALE_EN_GB, locales.get(2));
+ assertEquals(LOCALE_EN, locales.get(3));
+ }
+
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_JA_JP);
+ assertEquals(5, locales.size());
+ assertEquals(LOCALE_JA_JP, locales.get(0));
+ assertEquals(LOCALE_JA, locales.get(1));
+ assertEquals(LOCALE_EN_US, locales.get(2));
+ assertEquals(LOCALE_EN_GB, locales.get(3));
+ assertEquals(Locale.ENGLISH, locales.get(4));
+ }
+
+ // Test 3-letter language code.
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_FIL_PH);
+ assertEquals(5, locales.size());
+ assertEquals(LOCALE_FIL_PH, locales.get(0));
+ assertEquals(LOCALE_FIL, locales.get(1));
+ assertEquals(LOCALE_EN_US, locales.get(2));
+ assertEquals(LOCALE_EN_GB, locales.get(3));
+ assertEquals(Locale.ENGLISH, locales.get(4));
+ }
+
+ // Test variant.
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_TH_TH_TH);
+ assertEquals(6, locales.size());
+ assertEquals(LOCALE_TH_TH_TH, locales.get(0));
+ assertEquals(LOCALE_TH_TH, locales.get(1));
+ assertEquals(LOCALE_TH, locales.get(2));
+ assertEquals(LOCALE_EN_US, locales.get(3));
+ assertEquals(LOCALE_EN_GB, locales.get(4));
+ assertEquals(Locale.ENGLISH, locales.get(5));
+ }
+
+ // Test Locale extension.
+ {
+ final Locale localeWithoutVariant = LOCALE_JA_JP;
+ final Locale localeWithVariant = new Locale.Builder()
+ .setLocale(LOCALE_JA_JP)
+ .setExtension('x', "android")
+ .build();
+ assertFalse(localeWithoutVariant.equals(localeWithVariant));
+
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(localeWithVariant);
+ assertEquals(5, locales.size());
+ assertEquals(LOCALE_JA_JP, locales.get(0));
+ assertEquals(LOCALE_JA, locales.get(1));
+ assertEquals(LOCALE_EN_US, locales.get(2));
+ assertEquals(LOCALE_EN_GB, locales.get(3));
+ assertEquals(Locale.ENGLISH, locales.get(4));
+ }
+ }
}
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index c517201..377e6a16 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -58,21 +58,6 @@
<group gid="log" />
</permission>
- <permission name="android.permission.READ_EXTERNAL_STORAGE" perUser="true" >
- <group gid="sdcard_r" />
- </permission>
-
- <permission name="android.permission.WRITE_EXTERNAL_STORAGE" perUser="true" >
- <group gid="sdcard_r" />
- <group gid="sdcard_rw" />
- </permission>
-
- <permission name="android.permission.ACCESS_ALL_EXTERNAL_STORAGE" >
- <group gid="sdcard_r" />
- <group gid="sdcard_rw" />
- <group gid="sdcard_all" />
- </permission>
-
<permission name="android.permission.WRITE_MEDIA_STORAGE" >
<group gid="media_rw" />
</permission>
diff --git a/docs/html-intl/intl/es/design/get-started/principles.jd b/docs/html-intl/intl/es/design/get-started/principles.jd
new file mode 100644
index 0000000..351a4f7
--- /dev/null
+++ b/docs/html-intl/intl/es/design/get-started/principles.jd
@@ -0,0 +1,307 @@
+page.title=Principios de diseño para Android
+@jd:body
+
+<p>Estos principios de diseño fueron creados por el
+equipo de experiencia del usuario de Android para su propio uso, con el fin de tener siempre en cuenta lo mejor para los usuarios.
+En cuanto a los desarrolladores y diseñadores de Android, continúan
+utilizando las pautas de diseño más detalladas para los diferentes
+tipos de dispositivos.</p>
+
+<p>
+Tenga en cuenta estos principios cuando ponga en práctica su propia
+creatividad e ideas de diseño. Desvíese de lo tradicional con un propósito.
+</p>
+
+<h2 id="enchant-me">Cautívame</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="delight-me">Deléitame de formas sorprendentes</h4>
+<p>Una superficie atractiva, una animación colocada en el lugar correcto o un efecto de sonido bien sincronizado suelen ser experiencias
+placenteras. Los efectos sutiles contribuyen a crear un sentimiento de facilidad y la sensación de que se cuenta con una fuerza
+poderosa.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_delight.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="real-objects-more-fun">Los objetos reales son más divertidos que los botones y los menús</h4>
+<p>Permita que los usuarios toquen y manipulen directamente los objetos de su aplicación. Esto reduce el esfuerzo cognitivo
+que se necesita para llevar a cabo una tarea que resulte satisfactoria a nivel emocional.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_real_objects.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="make-it-mine">Permíteme darle un toque personal</h4>
+<p>A los usuarios les gusta agregar toques personales, ya que esto los ayuda a sentirse cómodos y a sentir que tienen el control. Ofrezca
+opciones predeterminadas prácticas y atractivas, pero también tenga en cuenta personalizaciones opcionales y divertidas que no entorpezcan las
+tareas principales.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_make_it_mine.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="get-to-know-me">Conóceme</h4>
+<p>Con el paso del tiempo, conozca las preferencias de los usuarios. En lugar de pedirles a los usuarios que elijan las mismas cosas una y otra
+vez, permita que puedan acceder fácilmente a las opciones que ya eligieron antes.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_get_to_know_me.png">
+
+ </div>
+</div>
+
+<h2 id="simplify-my-life">Simplifica mi vida</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="keep-it-brief">Sé breve</h4>
+<p>Utilice frases cortas con palabras simples. Las personas tienden a omitir las oraciones largas.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_keep_it_brief.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="pictures-faster-than-words">Las imágenes son más prácticas que las palabras</h4>
+<p>Considere la idea de utilizar imágenes para explicar las ideas. Las imágenes atraen la atención de las personas y pueden ser mucho más eficientes
+que las palabras.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_pictures.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="decide-for-me">Decide por mí, pero permíteme tener la última palabra</h4>
+<p>Siga su instinto y actúe sin preguntar primero. Tener que elegir demasiadas veces y tomar muchas decisiones hace que las personas
+se sientan molestas. Permita que los usuarios puedan deshacer sus elecciones en caso de que no sean lo que ellos desean.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_decide_for_me.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="only-show-when-i-need-it">Solo muéstrame lo que necesito, cuando lo necesito</h4>
+<p>Los usuarios se sienten abrumados cuando se les presenta demasiada información al mismo tiempo. Divida las tareas y la información en fragmentos pequeños
+y fáciles de digerir. Oculte las opciones que no son fundamentales en el momento y capacite a los usuarios sobre la marcha.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_information_when_need_it.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="always-know-where-i-am">Siempre debo saber dónde me encuentro</h4>
+<p>Haga que los usuarios sientan que conocen el camino de regreso. Para ello, diseñe las distintas partes de su aplicación de modo tal que se vean diferentes y
+utilice transiciones para mostrar la relación entre las pantallas. Proporcione comentarios sobre las tareas que están en curso.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_navigation.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="never-lose-my-stuff">Nunca pierdas lo que es mío</h4>
+<p>Guarde aquellas cosas que los usuarios crearon y permítales acceder a ellas desde cualquier lugar. Recuerde las configuraciones,
+los toques personales y las creaciones en todos los teléfonos, las tablets y las computadoras. Esta es la forma de hacer que las actualizaciones
+sean lo más simple del mundo.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_never_lose_stuff.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="looks-same-should-act-same">Si se ve igual, debe funcionar de la misma manera</h4>
+<p>Ayude a los usuarios a distinguir las diferencias funcionales al lograr que se vean diferentes en lugar de sutiles.
+Evite los modos, que son sitios que lucen similar pero actúan diferente ante la misma entrada.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_looks_same.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="interrupt-only-if-important">Solo interrúmpeme si es importante</h4>
+<p>Al igual que un buen asistente personal, evite a los usuarios los pormenores poco importantes. Las personas desean estar
+concentradas y, a menos que sea fundamental y esté sujeta a un plazo de tiempo, una interrupción puede resultar agobiante y frustrante.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_important_interruption.png">
+
+ </div>
+</div>
+
+<h2 id="make-me-amazing">Permíteme ser asombroso</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="give-me-tricks">Ofréceme trucos que funcionen en todos lados</h4>
+<p>Las personas se sienten muy bien cuando descubren cosas por sí mismos. Logre que su aplicación sea más simple de utilizar al
+aprovechar los patrones visuales y la memoria muscular de otras aplicaciones de Android. Por ejemplo, el gesto de deslizar rápidamente
+puede ser un buen acceso directo de navegación.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_tricks.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="its-not-my-fault">No es mi culpa</h4>
+<p>Sea sutil cuando les solicite a los usuarios que realicen correcciones. Ellos desean sentirse inteligentes cuando usan la
+aplicación que usted creó. Si hacen algo mal, bríndeles instrucciones claras de recuperación, pero evite darles detalles técnicos.
+Sería incluso mejor que usted lo solucione en segundo plano.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_error.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="sprinkle-encouragement">Fomenta lo simple</h4>
+<p>Desglose las tareas complejas en pasos más pequeños que se puedan cumplir fácilmente. Ofrezca comentarios sobre las acciones,
+incluso si es simplemente un halago sutil.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_sprinkle_encouragement.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="do-heavy-lifting-for-me">Haz el trabajo pesado por mí</h4>
+<p>Haga que los principiantes se sientan como expertos al permitirles hacer cosas que pensaron que nunca podrían hacer. Por
+ejemplo, a través de los accesos directos en los que se combinan múltiples efectos de fotografías, puede lograr que las fotografías de principiantes se vean maravillosas
+en solo algunos pasos.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_heavy_lifting.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="make-important-things-fast">Haz que lo importante sea rápido</h4>
+<p>No todas las acciones son iguales. Decida qué es lo más importante en su aplicación y haga
+que los usuarios lo puedan encontrar fácilmente y utilizar de forma rápida, como el obturador de una cámara o el botón de pausa de un reproductor de música.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_make_important_fast.png">
+
+ </div>
+</div>
diff --git a/docs/html-intl/intl/es/design/material/index.jd b/docs/html-intl/intl/es/design/material/index.jd
new file mode 100644
index 0000000..8cd3428
--- /dev/null
+++ b/docs/html-intl/intl/es/design/material/index.jd
@@ -0,0 +1,186 @@
+page.title=Material Design
+page.tags=Material,design
+page.type=design
+page.image=design/material/images/MaterialLight.png
+
+@jd:body
+
+<!-- developer docs box -->
+<a class="notice-developers right" href="{@docRoot}training/material/index.html">
+ <div>
+ <h3>Documentos para desarrolladores</h3>
+ <p>Creación de aplicaciones con Material Design</p>
+ </div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw">
+<div>
+ <h3>Video</h3>
+ <p>Introducción a Material Design</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw">
+<div>
+ <h3>Video</h3>
+ <p>Papel y tinta: los materiales más importantes</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc">
+<div>
+ <h3>Video</h3>
+ <p>Material Design en la aplicación Google I/O</p>
+</div>
+</a>
+
+
+
+<p itemprop="description">Material Design es una guía integral para el diseño visual, de movimientos y
+de interacción en distintas plataformas y dispositivos. Android ahora es compatible con las aplicaciones de
+Material Design. Para usar Material Design en sus aplicaciones de Android, siga las pautas descritas
+en la <a href="http://www.google.com/design/spec">especificación de Material Design</a> y use los
+nuevos componentes y funcionalidades disponibles en Android 5.0 (nivel de API 21) y versiones posteriores.</p>
+
+<p>En Android, se proporcionan los siguientes elementos que le permitirán crear aplicaciones en Material Design:</p>
+
+<ul>
+ <li>un tema nuevo;</li>
+ <li>nuevos widgets para vistas complejas;</li>
+ <li>nuevas API (interfaces de programación de aplicaciones) para sombras y animaciones personalizadas.</li>
+</ul>
+
+<p>Para obtener más información sobre la implementación de Material Design en Android, consulte
+<a href="{@docRoot}training/material/index.html">Creación de aplicaciones con Material Design</a>.</p>
+
+
+<h3>Tema Material</h3>
+
+<p>El tema Material le ofrece un nuevo estilo para su aplicación, widgets del sistema que le permiten configurar
+la paleta de colores y animaciones predeterminadas para información táctil y transiciones de actividades.</p>
+
+<!-- two columns -->
+<div style="width:700px;margin-top:25px;margin-bottom:20px">
+<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">Tema Dark Material</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">Tema Light Material</p>
+ </div>
+</div>
+<br style="clear:left"/>
+</div>
+
+<p>Para obtener más información, consulte <a href="{@docRoot}training/material/theme.html">Uso del tema
+Material</a>.</p>
+
+
+<h3>Listas y tarjetas</h3>
+
+<p>Android proporciona dos widgets nuevos para mostrar listas y tarjetas con estilos y
+animaciones de Material Design:</p>
+
+<!-- two columns -->
+<div style="width:700px;margin-top:25px;margin-bottom:20px">
+<div style="float:left;width:250px;margin-left:40px;margin-right:60px;">
+ <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" />
+ <p>El nuevo widget <code>RecyclerView</code> es una versión más acoplable de <code>ListView</code>
+ que admite diferentes tipos de diseños y proporciona mejoras en el rendimiento.</p>
+</div>
+<div style="float:left;width:250px;margin-right:0px;">
+ <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" />
+ <p>El nuevo widget <code>CardView</code> le permite mostrar extractos de información importante dentro de
+ tarjetas que tienen apariencia y estilo coherentes.</p>
+</div>
+<br style="clear:left"/>
+</div>
+
+<p>Para obtener más información, consulte <a href="{@docRoot}training/material/lists-cards.html">Creación de listas
+y tarjetas</a>.</p>
+
+
+<h3>Visualización de sombras</h3>
+
+<p>Además de las propiedades X e Y, las vistas de Android ahora poseen una
+propiedad Z. Esta propiedad nueva representa la elevación de una vista, que determina lo siguiente:</p>
+
+<ul>
+<li>El tamaño de la sombra: las vistas con valores Z más elevados proyectan sombras más grandes.</li>
+<li>El orden del dibujo: las vistas con valores Z más elevados aparecen sobre las otras vistas.</li>
+</ul>
+
+<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/videos/ContactsAnim.webm"/>
+ <source src="{@docRoot}design/videos/ContactsAnim.ogv"/>
+ </video>
+ </div>
+ <div style="font-size:10pt;margin-left:20px;margin-bottom:30px">
+ <em>Para volver a reproducir la película, haga clic en la pantalla del dispositivo.</em>
+ </div>
+</div>
+
+<p>Para obtener más información, consulte <a href="{@docRoot}training/material/shadows-clipping.html">Definición
+de vistas de recorte y sombras</a>.</p>
+
+
+<h3>Animaciones</h3>
+
+<p>Las nuevas API de animaciones le permiten crear animaciones personalizadas para la información táctil en los controles de IU,
+además de realizar cambios en el estado de las vistas y transiciones entre actividades.</p>
+
+<p>Estas API le permiten hacer lo siguiente:</p>
+
+<ul>
+<li style="margin-bottom:15px">
+responder a los eventos táctiles de sus vistas mediante animaciones de <strong>información táctil</strong>;
+</li>
+<li style="margin-bottom:15px">
+ocultar y mostrar vistas con animaciones con <strong>efecto circular</strong>;
+</li>
+<li style="margin-bottom:15px">
+alternar entre actividades con animaciones personalizadas de <strong>transición de actividades</strong>;
+</li>
+<li style="margin-bottom:15px">
+crear animaciones más naturales con <strong>movimiento curvo</strong>;
+</li>
+<li style="margin-bottom:15px">
+animar los cambios en una o más propiedades de las vistas con las animaciones de <strong>cambio de estado de la vista</strong>;
+</li>
+<li style="margin-bottom:15px">
+mostrar animaciones en los <strong>elementos de diseño de la lista de estados</strong> entre los cambios de estado de las vistas.
+</li>
+</ul>
+
+<p>Las animaciones de la información táctil se concentran en diferentes vistas estándar, como los botones. Las nuevas API
+le permiten personalizar estas animaciones y agregarlas a sus vistas personalizadas.</p>
+
+<p>Para obtener más información, consulte <a href="{@docRoot}training/material/animations.html">Definición de animaciones
+personalizadas</a>.</p>
+
+
+<h3>Elementos de diseño</h3>
+
+<p>Estas nuevas capacidades para los elementos de diseño le permiten implementar aplicaciones de Material Design:</p>
+
+<ul>
+<li>Los <strong>dibujables en vector</strong> se pueden escalar sin perder definición y son perfectos
+para los iconos de las aplicaciones de un solo color.</li>
+<li>El <strong>teñido de los dibujables</strong> le permite definir mapas de bits como máscaras alfa y pintarlos con
+un color durante el tiempo de ejecución.</li>
+<li>La <strong>extracción de color</strong> le permite extraer automáticamente colores prominentes de una
+imagen del mapa de bits.</li>
+</ul>
+
+<p>Para obtener más información, consulte <a href="{@docRoot}training/material/drawables.html">Trabajo con
+elementos de diseño</a>.</p>
diff --git a/docs/html-intl/intl/es/design/patterns/confirming-acknowledging.jd b/docs/html-intl/intl/es/design/patterns/confirming-acknowledging.jd
new file mode 100644
index 0000000..fbaa060
--- /dev/null
+++ b/docs/html-intl/intl/es/design/patterns/confirming-acknowledging.jd
@@ -0,0 +1,70 @@
+page.title=Confirmación y reconocimiento
+page.tags=dialog,toast,notification
+@jd:body
+
+<p>En algunos casos, cuando un usuario invoca una acción desde su aplicación, se recomienda <em>confirmar</em> o proporcionar un <em>reconocimiento</em> de dicha acción a través del texto.</p>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-6">
+ <img src="{@docRoot}design/media/confirm_ack_confirming.png">
+ <p><strong>Confirmación</strong> es solicitarle al usuario que verifique que realmente desea proceder con una acción que acaba de invocar. En algunos casos, la confirmación se presenta junto con una advertencia o mensaje con información importante relacionada con la acción que el usuario debe aprobar.</p>
+ </div>
+ <div class="layout-content-col span-6">
+ <img src="{@docRoot}design/media/confirm_ack_acknowledge.png">
+ <p>El <strong>reconocimiento</strong> hace referencia al hecho de mostrar un determinado texto para informarle al usuario que la acción que acaba de invocar ya se completó. De este modo, se elimina la incertidumbre sobre las operaciones implícitas que lleva a cabo el sistema. En algunos casos, el reconocimiento se presenta junto con una opción para deshacer la acción.</p>
+ </div>
+</div>
+
+<p>Comunicarse con los usuarios de este modo permite reducir la incertidumbre respecto de acciones pasadas o futuras. Mediante la confirmación o el reconocimiento también se puede evitar que los usuarios cometan errores de los que podrían arrepentirse.</p>
+
+<h2>Cuándo se debe solicitar una confirmación o proporcionar un reconocimiento de las acciones de los usuarios</h2>
+<p>No es necesario que se solicite una confirmación o se proporcione un reconocimiento para todas las acciones. Utilice este diagrama de flujo cuando tenga que tomar decisiones relacionadas con el diseño.</p>
+<img src="{@docRoot}design/media/confirm_ack_flowchart.png">
+
+<h2>Confirmación</h2>
+<div class="layout-content-row">
+ <div class="layout-content-col span-6">
+ <h4>Ejemplo: Google Play Books</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_books.png">
+ <p>En este ejemplo, el usuario solicitó eliminar un libro de su biblioteca de Google Play. Aparecerá una <a href="{@docRoot}design/building-blocks/dialogs.html#alerts">alerta</a> para confirmar esta acción porque es importante que el usuario comprenda que el libro ya no estará disponible desde ningún dispositivo.</p>
+ <p>Cuando diseñe un cuadro de diálogo de confirmación, asegúrese de que el título sea significativo y que incluya la acción solicitada.</p>
+ </div>
+ <div class="layout-content-col span-7">
+ <h4>Ejemplo: Android Beam</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_beam.png">
+ <p>No es necesario que las confirmaciones se presenten en todas las alertas con dos botones. Luego de iniciar Android Beam, se le solicita al usuario que seleccione el contenido que desea compartir (en este ejemplo, se trata de una fotografía). Si el usuario decide no continuar, simplemente se descartará el teléfono de la lista.</p>
+ </div>
+</div>
+
+<h2>Reconocimiento</h2>
+<div class="layout-content-row">
+ <div class="layout-content-col span-6">
+ <h4>Ejemplo: Borrador de Gmail abandonado y guardado</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_draftsave.png">
+ <p>En este ejemplo, si el usuario navega con los botones Back o Up desde la pantalla de redacción de Gmail, posiblemente ocurrirá algo inesperado: el borrador actual se guardará automáticamente. Esto se mostrará a través de un reconocimiento en forma de aviso. Dicho aviso desaparece luego de algunos segundos.</p>
+ <p>En este caso, no se puede incluir la opción de deshacer porque el almacenamiento fue iniciado por la aplicación, no por el usuario. Gracias a esto, se puede continuar redactando el mensaje de forma rápida y fácil con solo navegar hasta la lista de borradores.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+ <h4>Ejemplo: Conversación de Gmail eliminada</h4>
+ <img src="{@docRoot}design/media/confirm_ack_draft_deleted.png">
+ <p>Después de que el usuario elimina una conversación de la lista de Gmail, aparece un mensaje de reconocimiento con la opción de deshacer la acción. Dicho reconocimiento seguirá en pantalla hasta que el usuario lleve a cabo una acción no relacionada, como desplazarse por la lista.</p>
+ </div>
+</div>
+
+<h2>Sin confirmación ni reconocimiento</h2>
+<div class="layout-content-row">
+ <div class="layout-content-col span-6">
+ <h4>Ejemplo: Hacer +1</h4>
+ <img style="padding: 33px 0 30px;" src="{@docRoot}design/media/confirm_ack_ex_plus1.png">
+ <p><strong>No se necesita confirmación</strong>. Si el usuario hizo +1 sin querer, esto no es un problema. Simplemente, puede tocar el botón de nuevo para deshacer la acción.</p>
+ <p><strong>No se necesita un reconocimiento</strong>. El usuario verá que el botón +1 parpadea y cambia a color rojo. Esa es una señal muy clara.</p>
+ </div>
+ <div class="layout-content-col span-7">
+ <h4>Ejemplo: Eliminación de una aplicación de la pantalla de inicio</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_removeapp.png">
+ <p><strong>No se necesita confirmación</strong>. Esta es una acción intencionada: el usuario debe arrastrar y colocar un elemento en un destino relativamente grande y aislado. Por lo tanto, es poco probable que se cometan errores. No obstante, si el usuario se arrepiente de la decisión que tomó, solo demorará algunos segundos en recuperar lo eliminado.</p>
+ <p><strong>No se necesita un reconocimiento</strong>. El usuario sabrá que la aplicación ya no aparecerá en la Pantalla de inicio porque él mismo la hizo desaparecer al arrastrarla.</p>
+
+ </div>
+</div>
diff --git a/docs/html-intl/intl/es/design/patterns/navigation.jd b/docs/html-intl/intl/es/design/patterns/navigation.jd
new file mode 100644
index 0000000..6332491
--- /dev/null
+++ b/docs/html-intl/intl/es/design/patterns/navigation.jd
@@ -0,0 +1,213 @@
+page.title=Navegación con los botones Back y Up
+page.tags="navigation","activity","task","up navigation","back navigation"
+page.image=/design/media/navigation_between_siblings_gmail.png
+@jd:body
+
+<a class="notice-developers" href="{@docRoot}training/implementing-navigation/index.html">
+ <div>
+ <h3>Documentos para desarrolladores</h3>
+ <p>Implementación de la navegación eficiente</p>
+ </div>
+</a>
+
+<p itemprop="description">La navegación coherente es un componente fundamental de la experiencia general del usuario. Pocas situaciones frustran más a los
+usuarios que la navegación básica que se comporta de forma irregular e inesperada. En Android 3.0,
+se introdujeron cambios significativos en el comportamiento global de la navegación. Si sigue detalladamente
+las pautas de navegación con los botones Back y Up, la navegación en su aplicación será predecible y confiable para los usuarios.</p>
+<p>En Android 2.3 y versiones anteriores, se confió en el botón <em>Back</em> del sistema para respaldar la navegación dentro de una
+aplicación. Con la introducción de las barras de acciones en Android 3.0, apareció un segundo mecanismo de navegación:
+el botón <em>Up</em>, que consiste en el icono de la aplicación y una pequeña flecha a la izquierda.</p>
+
+<img src="{@docRoot}design/media/navigation_with_back_and_up.png">
+
+<h2 id="up-vs-back">Up en comparación con Back</h2>
+
+<p>El botón Up se utiliza para navegar dentro de una aplicación sobre la base de las relaciones jerárquicas
+entre pantallas. Por ejemplo, si en la pantalla A se muestra una lista de elementos y, si se selecciona un elemento, se conduce al usuario a la
+pantalla B (en la que se presenta ese elemento de forma más detallada), entonces en la pantalla B se debe mostrar el botón Up para regresar
+a la pantalla A.</p>
+<p>Si una pantalla aparece en la parte superior de una aplicación (es decir, en el inicio de la aplicación), no debe incluir el botón Up
+.</p>
+
+<p>El botón Back del sistema se utiliza para navegar, en orden cronológico inverso, por el historial
+de pantallas en las que recientemente trabajó el usuario. Generalmente, se basa en las relaciones temporales
+entre pantallas, y no en la jerarquía de la aplicación.</p>
+
+<p>Cuando la pantalla que se visitó anteriormente es también el componente jerárquico primario de la pantalla actual, si se presiona el botón
+Back, se obtendrá el mismo resultado que si se presiona el botón Up, y esto es algo que sucede a
+menudo. Sin embargo, a diferencia del botón Up, mediante el cual se garantiza que el usuario permanezca en la aplicación, el botón Back
+le permite al usuario regresar a la pantalla de inicio o, incluso, a otra aplicación.</p>
+
+<img src="{@docRoot}design/media/navigation_up_vs_back_gmail.png">
+
+<p>El botón Back también permite diferentes comportamientos que no están vinculados directamente con la navegación entre pantallas:
+</p>
+<ul>
+<li>descartar las ventanas flotantes (cuadros de diálogo o emergentes);</li>
+<li>descartar las barras de acción contextuales y eliminar el resaltado de los elementos seleccionados;</li>
+<li>ocultar el teclado en la pantalla (IME [Editores de métodos de entrada]).</li>
+</ul>
+<h2 id="within-app">Navegación dentro de su aplicación</h2>
+
+<h4>Navegación hacia pantallas con múltiples puntos de entrada</h4>
+<p>En algunos casos, las pantallas no tienen una posición fija dentro de la jerarquía de la aplicación, y se puede acceder a ellas
+desde múltiples puntos de entrada (como la pantalla Configuración, a la que se puede acceder desde cualquier otra pantalla
+de la aplicación). En este caso, el botón Up debe permitir regresar a la pantalla remitente, por lo que se comportaría
+de forma idéntica al botón Back.</p>
+<h4>Cambio de vista dentro de una pantalla</h4>
+<p>Cambiar las opciones de vista de una pantalla no modifica el comportamiento de los botones Up o Back: la pantalla sigue estando
+en el mismo lugar dentro de la jerarquía de la aplicación y no se crea ningún historial de navegación nuevo.</p>
+<p>Entre los ejemplos de cambios en las vistas, se encuentran los siguientes:</p>
+<ul>
+<li>cambio de vistas mediante las pestañas o los deslizamientos de izquierda a derecha;</li>
+<li>cambio de vistas mediante un menú desplegable (también conocido como pestañas colapsadas);</li>
+<li>filtrado de listas;</li>
+<li>clasificación de listas;</li>
+<li>modificación de las características de la pantalla (como el zoom).</li>
+</ul>
+<h4>Navegación entre pantallas relacionadas</h4>
+<p>Si su aplicación es compatible con la navegación desde una lista de elementos hacia una vista de detalles de alguno de esos elementos, generalmente,
+es preferible respaldar la navegación de dirección desde ese elemento a otro anterior
+o siguiente en la lista. Por ejemplo, en Gmail, es fácil deslizarse hacia la izquierda o la derecha desde una conversación
+para ver una conversación anterior o más nueva en la misma bandeja de entrada. Al igual que cuando se cambia la vista dentro de una pantalla, en este tipo de
+navegación no se cambia el comportamiento de los botones Up o Back.</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_gmail.png">
+
+<p>Sin embargo, una excepción importante a este caso se presenta cuando se explora entre vistas de detalles relacionadas que no están vinculadas
+mediante la lista que se está utilizando; por ejemplo, cuando se explora en Play Store entre diferentes aplicaciones
+del mismo desarrollador o entre álbumes del mismo artista. En estos casos, si se sigue cada vínculo, esto queda registrado en el
+historial, por lo que, a través del botón Back, se regresa a cada pantalla que se visitó anteriormente. El botón Up debe seguir omitiendo
+estas pantallas relacionadas y navegar hacia la pantalla del contenedor visitada más recientemente.</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_market1.png">
+
+<p>Usted puede lograr que el comportamiento del botón Up sea incluso más inteligente teniendo en cuenta sus conocimientos de la vista
+detallada. Si extendemos el ejemplo de Play Store mencionado antes, imaginemos que el usuario navegó desde el último
+libro visto hacia los detalles de la adaptación de la película. En ese caso, mediante el botón Up podrá regresar a un contenedor
+(Películas) por el que el usuario no navegó anteriormente.</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_market2.png">
+
+<h2 id="into-your-app">Navegación dentro de la aplicación a través de los widgets y las notificaciones de la pantalla de inicio</h2>
+
+<p>Podrá utilizar los widgets y las notificaciones de la pantalla de inicio para ayudar a los usuarios a navegar directamente hacia las pantallas
+que se encuentran en posiciones más profundas dentro de la jerarquía de su aplicación. Por ejemplo, tanto el widget de la bandeja de entrada de Gmail como las notificaciones de los mensajes nuevos
+ pueden omitir la pantalla Bandeja de entrada y llevar al usuario directamente hacia una vista de conversación.</p>
+
+<p>En ambos casos, el botón Up se debe utilizar de la siguiente manera:</p>
+
+<ul>
+<li><em>Si a la pantalla de destino generalmente se llega desde una determinada pantalla dentro de su
+aplicación</em>, el botón Up debe permitir la navegación hacia esa pantalla.</li>
+<li><em>De lo contrario, </em>el botón Up debe permitir la navegación hacia la pantalla que está en el nivel superior ("Inicio") de su aplicación.</li>
+</ul>
+
+<p>En el caso del botón Back, la navegación debe ser más predecible. Para ello, coloque en la
+pila de retroceso de la tarea la ruta completa de la navegación ascendente hacia la pantalla que se encuentra en el nivel superior de la aplicación. De este modo, los usuarios que
+no recuerdan cómo ingresaron a su aplicación podrán navegar hacia la pantalla del nivel superior de la aplicación antes de
+salir.</p>
+
+<p>A modo de ejemplo, el widget de la pantalla Inicio de Gmail posee un botón para llevar al usuario directamente a la pantalla de
+redacción. Mediante los botones Up o Back de la pantalla de redacción el usuario debería poder dirigirse hacia la Bandeja de entrada y, a partir de allí, continuar hacia la pantalla Inicio
+por medio del botón Back.</p>
+
+<img src="{@docRoot}design/media/navigation_from_outside_back.png">
+
+<h4>Notificaciones indirectas</h4>
+
+<p>Cuando su aplicación necesita presentar información sobre múltiples eventos de forma simultánea, puede utilizar una
+sola notificación que dirija al usuario a una pantalla intersticial. En esta pantalla, se resumen dichos
+eventos y se proporcionan rutas para que el usuario navegue más profundamente por la aplicación. Las notificaciones de este estilo se
+denominan <em>notificaciones indirectas</em>.</p>
+
+<p>A diferencia de las notificaciones estándar (directas), si se presiona Back desde una pantalla intersticial de una
+notificación indirecta, el usuario será dirigido hacia el punto en el que se desencadenó la notificación. No se incluyen
+pantallas adicionales en la pila de retroceso. Una vez que el usuario se dirige hacia la aplicación desde la
+pantalla intersticial, los botones Up y Back se comportan del mismo modo que lo hacen en las notificaciones estándar, como se describió antes:
+navegan dentro de la aplicación en lugar de regresar a la pantalla intersticial.</p>
+
+<p>Por ejemplo, supongamos que un usuario de Gmail recibe una notificación indirecta del calendario Si se toca
+esta notificación, se abrirá la pantalla intersticial, en la que se mostrarán recordatorios de varios
+eventos diferentes. Si se toca Back desde la pantalla intersticial, el usuario volverá a Gmail. Si se toca un evento
+en particular, el usuario saldrá de la pantalla intersticial e ingresará en la aplicación Calendario, donde se mostrarán detalles del
+evento. En la pantalla de detalles del evento, es posible navegar con los botones Up y Back hacia la vista superior del calendario.</p>
+
+<img src="{@docRoot}design/media/navigation_indirect_notification.png">
+
+<h4>Notificaciones emergentes</h4>
+
+<p><em>Las notificaciones emergentes</em> omiten el panel lateral de notificaciones y aparecen directamente
+frente al usuario. Estas casi nunca se utilizan, y se <strong>deben reservar para ocasiones en las que es necesario proporcionar una
+respuesta oportuna y es necesario realizar una interrupción en el contexto del usuario</strong>. Por ejemplo,
+en Talk se utiliza este estilo para alertar al usuario sobre una invitación de un amigo para participar en una videocharla, ya que esta
+invitación caducará automáticamente luego de algunos segundos.</p>
+
+<p>En términos de comportamiento de la navegación, las notificaciones emergentes siguen, en gran medida, el comportamiento de la pantalla intersticial
+de una notificación indirecta. El botón Back le permite al usuario descartar la notificación emergente. Si el usuario navega
+desde la ventana emergente hacia la aplicación que genera las notificaciones, los botones Up y Back seguirán las reglas para las notificaciones estándar
+mientras se navega por la aplicación.</p>
+
+<img src="{@docRoot}design/media/navigation_popup_notification.png">
+
+<h2 id="between-apps">Navegación entre aplicaciones</h2>
+
+<p>Una de las principales ventajas del sistema Android es la capacidad de las aplicaciones de activarse
+mutuamente, por lo que el usuario puede navegar directamente desde una aplicación hacia otra. Por ejemplo, una
+aplicación que debe tomar una fotografía puede activar la aplicación de la cámara, la cual mostrará la fotografía
+en la aplicación que la activó. Esto representa una gran ventaja tanto para el desarrollador, quien puede aprovechar fácilmente el
+código de otras aplicaciones, y también para el usuario, quien disfruta de una experiencia coherente para acciones
+que se realizan comúnmente.</p>
+
+<p>Para comprender la navegación entre aplicaciones, es importante que entienda el comportamiento del marco de Android,
+que se explica a continuación.</p>
+
+<h4>Actividades, tareas e intentos</h4>
+
+<p>En Android, una <strong>actividad</strong> es un componente de la aplicación que define una pantalla de
+información y todas las acciones relacionadas que el usuario puede llevar a cabo. Su aplicación es un conjunto de
+actividades formado por las actividades que usted crea y aquellas que reutiliza de otras aplicaciones.</p>
+
+<p>Una <strong>tarea</strong> es la secuencia de actividades que un usuario realiza para lograr un objetivo. En
+una sola tarea, se pueden utilizar actividades de una sola aplicación o se pueden utilizar actividades de varias
+aplicaciones diferentes.</p>
+
+<p>Un <strong>intento</strong> es un mecanismo mediante el cual una aplicación indica que necesita la ayuda de
+otra aplicación para realizar una acción. Las actividades de una aplicación pueden indicar los intentos
+a los que pueden dar respuesta. En el caso de los intentos comunes, como "Compartir", es posible que el usuario tenga instaladas varias aplicaciones
+que pueden cumplir con esta solicitud.</p>
+
+<h4>Ejemplo: navegación entre aplicaciones para respaldar el uso compartido</h4>
+
+<p>Para comprender cómo las actividades, las tareas y los intentos funcionan en conjunto, considere cómo una aplicación les permite a los usuarios
+compartir contenido a través de otra aplicación. Por ejemplo, si ejecuta la aplicación Play Store desde la pantalla de inicio, se iniciará
+una nueva tarea A (vea la imagen a continuación). Después de navegar por Play Store y de tocar un libro promocionado
+para ver la información detallada, el usuario permanece en la misma tarea y la extiende al agregar actividades. Si se desencadena la acción
+Compartir, se le mostrará al usuario un cuadro de diálogo con una lista de todas las actividades (provenientes de diferentes aplicaciones)
+que se registraron para concretar el intento de compartir.</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_inward.png">
+
+<p>Si el usuario decide compartir el contenido a través de Gmail, la actividad de redacción de Gmail se agrega como una continuación de la
+tarea A; no se crea una tarea nueva. Si Gmail estaba ejecutando su propia tarea en segundo plano, esta
+no debería verse afectada.</p>
+
+<p>Desde la actividad de redacción, si se envía el mensaje o se toca el botón Back, se dirigirá nuevamente al usuario hacia
+la actividad de detalles del libro. Si se sigue tocando el botón Back, el usuario seguirá navegando por Play
+Store y, finalmente, llegará a la pantalla de inicio.</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_back.png">
+
+<p>Sin embargo, si el usuario toca el botón Up desde la actividad de redacción, estará indicando su deseo de permanecer dentro de
+Gmail. Por consiguiente, aparecerá la actividad de la lista de conversaciones de Gmail y se creará una nueva tarea B para esto. La ruta raíz de las nuevas tareas siempre conduce
+a la pantalla Inicio, por lo que, si se toca el botón Back desde la lista de conversaciones, se regresará a dicha pantalla.</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_up.png">
+
+<p>La tarea A permanece en segundo plano, y el usuario podrá regresar a ella después (por ejemplo, a través de la pantalla
+Recientes). Si Gmail ya estaba ejecutando su propia tarea en segundo plano, esta se reemplazará con la
+tarea B, y el contexto anterior se abandonará para darle preferencia al nuevo objetivo del usuario.</p>
+
+<p>Cuando su aplicación se registre para manipular los intentos de una actividad que se encuentra en un nivel profundo dentro de la jerarquía de la aplicación,
+consulte <a href="#into-your-app">Navegación dentro de la aplicación a través de los widgets y
+las notificaciones de la pantalla de inicio</a> para obtener información sobre cómo especificar la navegación del botón Up.</p>
diff --git a/docs/html-intl/intl/es/design/patterns/notifications.jd b/docs/html-intl/intl/es/design/patterns/notifications.jd
new file mode 100644
index 0000000..bdbc77b
--- /dev/null
+++ b/docs/html-intl/intl/es/design/patterns/notifications.jd
@@ -0,0 +1,872 @@
+page.title=Notificaciones
+page.tags="notifications","design","L"
+@jd:body
+
+ <a class="notice-developers" href="{@docRoot}training/notify-user/index.html">
+ <div>
+ <h3>Documentos para desarrolladores</h3>
+ <p>Cómo notificar al usuario</p>
+ </div>
+</a>
+
+<a class="notice-designers" href="notifications_k.html">
+ <div>
+ <h3>Notificaciones en Android 4.4 y versiones anteriores</h3>
+ </div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=Uiq2kZ2JHVY">
+<div>
+ <h3>Video</h3>
+ <p>DevBytes: Notificaciones en la vista previa para desarrolladores de Android L</p>
+</div>
+</a>
+
+<style>
+ .col-5, .col-6, .col-7 {
+ margin-left:0px;
+ }
+</style>
+
+<p>El sistema de notificaciones les permite a los usuarios mantenerse informados sobre eventos relevantes y
+oportunos
+de su aplicación, como nuevos mensajes de chat de un amigo o un evento del calendario.
+Piense en las notificaciones como un canal de noticias que alerta a los usuarios sobre eventos
+importantes
+a medida que se producen o como un registro en el que se relatan los eventos mientras el usuario no está prestando
+atención y que se sincroniza de forma correspondiente en todos los dispositivos de Android.</p>
+
+<h4 id="New"><strong>Novedades de Android 5.0</strong></h4>
+
+<p>En Android 5.0, las notificaciones reciben actualizaciones importantes a nivel estructural,
+visual y funcional.</p>
+
+<ul>
+ <li>En las notificaciones, se han realizado cambios visuales de forma coherente con el nuevo
+tema Material Design.</li>
+ <li> Las notificaciones ahora están disponibles en la pantalla de bloqueo del dispositivo y
+el contenido confidencial se puede seguir
+ ocultando detrás de dicha pantalla.</li>
+ <li>En las notificaciones de alta prioridad que se reciben cuando el dispositivo está en uso, ahora se utiliza un nuevo formato llamado
+ notificaciones emergentes.</li>
+ <li>Notificaciones sincronizadas en la nube: Si se omite una notificación en un dispositivo
+Android, esta se omitirá
+ también en los demás dispositivos.</li>
+</ul>
+
+<p class="note"><strong>Nota:</strong> El diseño de las notificaciones de esta versión de
+Android se diferencia
+de manera significativa del diseño de las versiones anteriores. Para obtener información sobre el diseño de las notificaciones en versiones
+anteriores, consulte <a href="./notifications_k.html">Notificaciones en Android 4.4 y versiones anteriores</a>.</p>
+
+<h2 id="Anatomy">Anatomía de una notificación</h2>
+
+<p>En esta sección, se repasan las partes básicas de una notificación y cómo se pueden mostrar en
+diferentes tipos de dispositivos.</p>
+
+<h3 id="BaseLayout">Diseño básico</h3>
+
+<p>Como mínimo, todas las notificaciones poseen un diseño básico que incluye lo siguiente:</p>
+
+<ul>
+ <li> El <strong>icono</strong> de la notificación. El icono simboliza la
+aplicación que lo origina. También puede
+ indicar el tipo de notificación si la aplicación genera más de un
+tipo.</li>
+ <li> <strong>Título</strong> de la notificación y
+<strong>texto</strong> adicional.</li>
+ <li> Una <strong>marca de tiempo</strong>.</li>
+</ul>
+
+<p>Las notificaciones creadas con {@link android.app.Notification.Builder Notification.Builder}
+para versiones anteriores de la plataforma lucen y funcionan igual en Android
+5.0; solo presentan algunos cambios de estilo que el sistema realiza
+por usted. Para obtener más información sobre las notificaciones en versiones anteriores de
+Android, consulte
+<a href="./notifications_k.html">Notificaciones en Android 4.4 y versiones anteriores</a>.</p></p>
+
+
+ <img style="margin:20px 0 0 0" src="{@docRoot}images/android-5.0/notifications/basic_combo.png" alt="" width="700px" />
+
+
+<div style="clear:both;margin-top:20px">
+ <p class="img-caption">
+ Diseño básico de una notificación para dispositivos portátiles (izquierda) y la misma notificación en Wear (derecha),
+ con una fotografía del usuario y un icono de la notificación
+ </p>
+ </div>
+
+<h3 id="ExpandedLayouts">Diseños expandidos</h3>
+
+
+<p>Usted puede decidir cuántos detalles mostrarán las notificaciones
+de su aplicación. Las notificaciones pueden mostrar las primeras
+líneas de un mensaje o la vista previa de una imagen más grande. A través de la
+información adicional, se proporciona más
+contexto al usuario y, en algunos casos, se puede permitir que el usuario lea todo el
+mensaje. El usuario
+puede acercar o alejar la imagen, o deslizar la imagen con un solo dedo para alternar entre los diseños compacto
+y expandido.
+ En el caso de las notificaciones de un solo evento, Android proporciona tres plantillas de
+diseños expandidos (texto, bandeja de entrada e
+ imagen) para que usted utilice en su aplicación. En las siguientes imágenes, se muestra cómo
+se ven las notificaciones de un solo evento en los
+ dispositivos portátiles (izquierda) y los dispositivos con Wear (derecha).</p>
+
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/expandedtext_combo.png"
+ alt="" width="700px" height;="284px" />
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/stack_combo.png"
+ alt="" width="700px" height;="284px" />
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/ExpandedImage.png"
+ alt="" width="311px" height;="450px" />
+
+<h3 id="actions" style="clear:both; margin-top:40px">Acciones</h3>
+
+<p>Android es compatible con acciones opcionales que se muestran en la parte inferior
+de la notificación.
+A través de las acciones, los usuarios pueden administrar las tareas más comunes para una determinada
+notificación desde el interior del panel de notificaciones, sin tener que abrir la
+aplicación que la originó.
+Esto acelera la interacción y, junto con la función deslizar para descartar, ayuda a los usuarios a enfocarse en las
+notificaciones que les parecen importantes.</p>
+
+
+ <img src="{@docRoot}images/android-5.0/notifications/action_combo.png" alt="" width="700px" />
+
+
+
+<p style="clear:both">Sea moderado con la cantidad de acciones que incluye en una
+notificación. Mientras más
+acciones incluya, mayor complejidad cognitiva generará. Limítese a
+la menor cantidad posible
+de acciones al incluir solo las acciones más importantes
+y significativas.</p>
+
+<p>Las acciones recomendadas para las notificaciones son aquellas que:</p>
+
+<ul>
+ <li> Son fundamentales, frecuentes y típicas para el tipo de contenido que está
+mostrando.
+ <li> Les permiten a los usuarios realizar las tareas rápidamente.
+</ul>
+
+<p>Evite acciones que sean:</p>
+
+<ul>
+ <li> ambiguas;
+ <li> iguales que la acción predeterminada de la notificación (tales como "Leer" o
+"Abrir").
+</ul>
+
+
+
+<p>Puede especificar un máximo de tres acciones, cada una de ellas formada por un icono
+de la acción y un nombre.
+ Al agregarle acciones a un diseño básico simple, la notificación será expandible,
+incluso si no
+ cuenta con un diseño expandido. Como las acciones solo se muestran en las notificaciones
+expandidas
+ y, de lo contrario, se ocultan, asegúrese de que cualquier acción que el
+usuario invoque desde
+ una notificación esté disponible también desde la aplicación
+asociada.</p>
+
+<h2 style="clear:left">Notificación emergente</h2>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/hun-example.png" alt="" width="311px" />
+ <p class="img-caption">
+ Ejemplo de una notificación emergente (llamada telefónica entrante, alta prioridad)
+que aparece en la parte superior de una
+ aplicación inmersiva
+ </p>
+</div>
+
+<p>Cuando llega una notificación de alta prioridad (ver a la derecha), esta se presenta
+a los usuarios
+durante un período breve, con un diseño expandido que expone las posibles acciones.</p>
+<p> Luego de este período, la notificación se retira hacia el
+panel de notificaciones. Si la <a href="#correctly_set_and_manage_notification_priority">prioridad</a> de una notificación
+se marca como Alta, Máxima o Pantalla completa, se obtiene una notificación emergente.</p>
+
+<p><b>Buenos ejemplos de notificaciones emergentes</b></p>
+
+<ul>
+ <li> Llamada telefónica entrante cuando se utiliza un dispositivo</li>
+ <li> Alarma cuando se utiliza un dispositivo</li>
+ <li> Nuevo mensaje SMS</li>
+ <li> Batería baja</li>
+</ul>
+
+<h2 style="clear:both" id="guidelines">Pautas</h2>
+
+
+<h3 id="MakeItPersonal">Personalización</h3>
+
+<p>En el caso de las notificaciones de los elementos que envía otra persona (como un mensaje o una
+actualización de estado), utilice
+{@link android.app.Notification.Builder#setLargeIcon setLargeIcon()} para incluir la imagen de esa persona. Además, adjunte información sobre
+la persona en los metadatos de la notificación (consulte {@link android.app.Notification#EXTRA_PEOPLE}).</p>
+
+<p>El icono principal de su notificación seguirá estando visible, de modo que el usuario pueda asociarlo
+con el icono
+que se muestra en la barra de estado.</p>
+
+
+<img src="{@docRoot}images/android-5.0/notifications/Triggered.png" alt="" width="311px" />
+<p style="margin-top:10px" class="img-caption">
+ Notificación en la que se muestra la persona que la generó y el contenido que envió.
+</p>
+
+
+<h3 id="navigate_to_the_right_place">Navegación hacia el lugar correcto</h3>
+
+<p>Cuando el usuario toca el cuerpo de una notificación (fuera de los botones de acción
+), esta se abre
+en el lugar en el que el usuario puede visualizarla y utilizar los datos que se mencionan en la
+notificación. En la mayoría de los casos, se tratará de la vista detallada de un solo elemento de datos como un mensaje,
+pero también se podría tratar de una
+vista resumida si la notificación está apilada. Si la aplicación dirige al
+usuario a cualquier sitio que se encuentre debajo del nivel superior, incorpore la navegación en la pila de retroceso de la aplicación para que el
+usuario pueda presionar el botón Back del sistema y regresar al nivel superior. Para obtener más información, consulte
+<em>Navegación dentro de la aplicación a través de los widgets y las notificaciones de la pantalla de Inicio</em> en el patrón de
+diseño <a href="{@docRoot}design/patterns/navigation.html#into-your-app">Navegación</a>.</p>
+
+<h3 id="correctly_set_and_manage_notification_priority">Configuración y administración
+correctas de la prioridad
+de las notificaciones</h3>
+
+<p>Android admite el uso de una marca de prioridad en las notificaciones. Esta marca
+le permite influir en el lugar donde aparecerá la notificación, en relación con otras notificaciones, y
+lo ayuda a asegurarse de
+que los usuarios vean siempre primero las notificaciones más importantes. Cuando publica una notificación, puede elegir
+entre los
+siguientes niveles de prioridad:</p>
+<table>
+ <tr>
+ <td class="tab0">
+<p><strong>Prioridad</strong></p>
+</td>
+ <td class="tab0">
+<p><strong>Uso</strong></p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>MAX</code></p>
+</td>
+ <td class="tab1">
+<p>Utilícelo para las notificaciones críticas y urgentes en las que se le informa al usuario sobre una condición
+que es
+crítica en el tiempo o que se debe resolver antes de que el usuario continúe con una
+tarea específica.</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>HIGH</code></p>
+</td>
+ <td class="tab1">
+<p>Utilícelo, principalmente, para comunicaciones importantes, como eventos de mensajes o
+chats con contenido que sea particularmente interesante para el usuario.
+Las notificaciones de alta prioridad activan la pantalla de notificaciones emergentes.</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>DEFAULT</code></p>
+</td>
+ <td class="tab1">
+<p>Utilícelo para todas las notificaciones que no pertenecen a ninguno de los otros tipos de prioridades que se describen aquí.</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>LOW</code></p>
+</td>
+ <td class="tab1">
+<p>Utilícelo para las notificaciones que desea que el usuario reciba, pero
+que son menos urgentes. Las notificaciones de baja prioridad tienden a aparecer en la parte inferior de la lista,
+por lo que son ideales para
+eventos como actualizaciones sociales públicas o indirectas: El usuario solicitó que se le notifiquen
+estas
+actualizaciones, pero estas notificaciones nunca tendrán prioridad sobre las comunicaciones
+urgentes o directas.</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>MIN</code></p>
+</td>
+ <td class="tab1">
+<p>Utilícelo para la información contextual o de segundo plano, como información sobre el clima o la
+ubicación contextual.
+Las notificaciones cuya prioridad es mínima no aparecen en la barra de estado. El usuario
+las descubre al expandir el panel de notificaciones.</p>
+</td>
+ </tr>
+</table>
+
+
+<h4 id="how_to_choose_an_appropriate_priority"><strong>Cómo elegir la
+prioridad
+adecuada</strong></h4>
+
+<p><code>DEFAULT</code>, <code>HIGH</code> y <code>MAX</code> son niveles de prioridad interruptiva, y se corre el riesgo de
+interrumpir al usuario
+en el medio de su actividad. Para evitar incomodar a los usuarios de su aplicación, reserve los niveles de prioridad interruptiva para
+las notificaciones:</p>
+
+<ul>
+ <li> en las que participe otra persona;</li>
+ <li> en las que el tiempo sea importante;</li>
+ <li> que puedan modificar inmediatamente el comportamiento del usuario en el mundo real.</li>
+</ul>
+
+<p>Las notificaciones que se configuran en <code>LOW</code> y <code>MIN</code> pueden seguir siendo
+valiosas para el usuario: muchas, tal vez la mayoría, de las notificaciones simplemente no le piden al usuario que actúe de inmediato
+ni llaman su atención mediante una vibración, pero poseen información que será valiosa para el
+usuario
+cuando este decida ver las notificaciones. Entre los criterios de las notificaciones con prioridad <code>LOW</code> y <code>MIN</code>,
+se incluyen los siguientes:</p>
+
+<ul>
+ <li> No participan otras personas.</li>
+ <li> El tiempo no es importante.</li>
+ <li> Incluyen contenido que podría interesarle al usuario, pero que tal vez desee
+buscarlo cuando lo necesite.</li>
+</ul>
+
+
+ <img src="{@docRoot}images/android-5.0/notifications/notifications_pattern_priority.png" alt="" width="700" />
+
+
+<h3 style="clear:both" id="set_a_notification_category">Configuración de una
+categoría de notificaciones</h3>
+
+<p>Si su notificación se puede clasificar dentro de alguna de las categorías predefinidas (consulte
+a continuación), asígnela
+según corresponda. Esta información se puede utilizar en determinados aspectos de la IU del sistema, como el panel de notificaciones (o cualquier
+otro
+agente de escucha de la notificación), para realizar una clasificación y filtrar las decisiones.</p>
+<table>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_CALL">CATEGORY_CALL</a></code></p>
+</td>
+ <td>
+<p>Llamada entrante (voz o video) o una solicitud de comunicación
+sincrónica similar</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_MESSAGE">CATEGORY_MESSAGE</a></code></p>
+</td>
+ <td>
+<p>Mensaje entrante directo (SMS, mensaje instantáneo, etc.)</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_EMAIL">CATEGORY_EMAIL</a></code></p>
+</td>
+ <td>
+<p>Mensaje en bloque asíncrono (correo electrónico)</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_EVENT">CATEGORY_EVENT</a></code></p>
+</td>
+ <td>
+<p>Evento del calendario</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_PROMO">CATEGORY_PROMO</a></code></p>
+</td>
+ <td>
+<p>Promoción o anuncio</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_ALARM">CATEGORY_ALARM</a></code></p>
+</td>
+ <td>
+<p>Alarma o temporizador</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_PROGRESS">CATEGORY_PROGRESS</a></code></p>
+</td>
+ <td>
+<p>Progreso de una operación en segundo plano de larga ejecución</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SOCIAL">CATEGORY_SOCIAL</a></code></p>
+</td>
+ <td>
+<p>Actualización de red social o uso compartido de datos</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_ERROR">CATEGORY_ERROR</a></code></p>
+</td>
+ <td>
+<p>Error en una operación en segundo plano o un estado de autenticación</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_TRANSPORT">CATEGORY_TRANSPORT</a></code></p>
+</td>
+ <td>
+<p>Control de transporte de medios para la reproducción</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SYSTEM">CATEGORY_SYSTEM</a></code></p>
+</td>
+ <td>
+<p>Actualización del estado del dispositivo o el sistema. Reservado para ser utilizado por el sistema</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SERVICE">CATEGORY_SERVICE</a></code></p>
+</td>
+ <td>
+<p>Indicación de ejecución de servicio en segundo plano</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_RECOMMENDATION">CATEGORY_RECOMMENDATION</a></code></p>
+</td>
+ <td>
+<p>Una recomendación específica y oportuna para un solo evento. Por ejemplo, en una
+aplicación de noticias tal vez se desee
+recomendar una historia que se considere que el usuario deseará leer luego</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_STATUS">CATEGORY_STATUS</a></code></p>
+</td>
+ <td>
+<p>Información constante sobre el estado contextual o del dispositivo</p>
+</td>
+ </tr>
+</table>
+
+<h3 id="summarize_your_notifications">Resumen de las notificaciones</h3>
+
+<p>Si una notificación de un determinado tipo ya está pendiente cuando su aplicación intenta enviar una nueva
+notificación del mismo tipo, combínelas en una misma notificación resumida para la aplicación. No
+cree un objeto nuevo.</p>
+
+<p>Las notificaciones resumidas incluirán una descripción resumida y le permitirán al usuario
+conocer cuántas
+notificaciones de un determinado tipo están pendientes.</p>
+
+<div class="col-6">
+
+<p><strong>Lo que no debe hacer</strong></p>
+ <img src="{@docRoot}images/android-5.0/notifications/Summarise_Dont.png" alt="" width="311px" />
+</div>
+
+<div>
+<p><strong>Lo que debe hacer</strong></p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/Summarise_Do.png" alt="" width="311px" />
+</div>
+
+<p style="clear:left; padding-top:30px; padding-bottom:20px">Puede proporcionar
+información más detallada sobre cada una de las notificaciones que conforman un
+ resumen al utilizar el diseño resumido expandido. Este enfoque les permite a los usuarios tener
+una idea más clara de las
+ notificaciones pendientes y determinar si están lo suficientemente interesados como para leer
+los detalles en la
+ aplicación asociada.</p>
+<div class="col-6">
+ <img src="{@docRoot}images/android-5.0/notifications/Stack.png" style="margin-bottom:20px" alt="" width="311px" />
+ <p class="img-caption">
+ Notificación contraída y expandida que es un resumen (mediante el uso de <code>InboxStyle</code>)
+ </p>
+</div>
+
+<h3 style="clear:both" id="make_notifications_optional">Uso de notificaciones
+opcionales</h3>
+
+<p>Los usuarios deben tener siempre el control sobre las notificaciones. Permítale al usuario
+deshabilitar las notificaciones
+de su aplicación o cambiar las propiedades de las alertas, como el sonido de una alerta y si desea
+utilizar la vibración,
+mediante la incorporación de un elemento de configuración de notificaciones en las configuraciones de la aplicación.</p>
+
+<h3 id="use_distinct_icons">Uso de iconos diferentes</h3>
+<p>Al mirar el área de notificaciones, el usuario debe poder diferenciar
+los tipos de
+notificaciones que están pendientes actualmente.</p>
+
+<div class="figure">
+ <img src="{@docRoot}images/android-5.0/notifications/ProductIcons.png" alt="" width="420" />
+</div>
+
+ <div><p><strong>Lo que debe hacer</strong></p>
+ <p>Mirar los iconos de notificaciones que ya se proporcionan en las aplicaciones de Android y crear
+iconos de notificaciones para
+ su aplicación que tengan una apariencia bastante diferente.</p>
+
+ <p><strong>Lo que debe hacer</strong></p>
+ <p>Utilizar el <a href="/design/style/iconography.html#notification">estilo de icono de notificación</a>
+ adecuado para los iconos pequeños y el
+<a href="/design/style/iconography.html#action-bar">estilo
+de icono de barra de acción</a> del diseño Material Light para los iconos
+ de acciones.</p>
+<p ><strong>Lo que debe hacer</strong></p>
+<p >Hacer que los iconos sean simples y evitar incluir una cantidad excesiva de detalles difíciles de
+distinguir.</p>
+
+ <div><p><strong>Lo que no debe hacer</strong></p>
+ <p>Colocar valores alfa adicionales (que se oscurezcan o aclaren) en los
+iconos pequeños y los
+ iconos de acciones. Estos pueden tener bordes alisados, pero como en Android estos iconos se utilizan
+como máscaras (es decir, solo se
+ utiliza el canal alfa), por lo general, la imagen se debe dibujar con
+opacidad completa.</p>
+
+</div>
+<p style="clear:both"><strong>Lo que no debe hacer</strong></p>
+
+<p>Utilizar colores para diferenciar su aplicación de las demás. Los iconos de las notificaciones simplemente
+deben ser una imagen sobre un fondo blanco o transparente.</p>
+
+
+<h3 id="pulse_the_notification_led_appropriately">Pulsación adecuada del
+LED de notificaciones</h3>
+
+<p>Muchos dispositivos con Android incluyen un LED de notificaciones, que se utiliza para mantener al
+usuario informado sobre los
+eventos cuando la pantalla está apagada. Las notificaciones con un nivel de prioridad <code>MAX</code>,
+<code>HIGH</code> o <code>DEFAULT</code> deben
+hacer que se encienda el LED, mientras que las de menor prioridad (<code>LOW</code> y
+<code>MIN</code>) no deben activar esta función.</p>
+
+<p>El control del usuario sobre las notificaciones debe extenderse al LED. Cuando se utilice
+DEFAULT_LIGHTS, el
+LED se iluminará en color blanco. Sus notificaciones no deberían utilizar un color
+diferente, a menos que el
+usuario lo haya personalizado explícitamente.</p>
+
+<h2 id="building_notifications_that_users_care_about">Creación de notificaciones
+importantes para los usuarios</h2>
+
+<p>Para crear una aplicación que les guste a los usuarios, es importante diseñar las notificaciones
+cuidadosamente.
+Las notificaciones son la voz de su aplicación y ayudan a definir su
+personalidad. Las notificaciones no deseadas
+o que no son importantes pueden hacer que el usuario se moleste o no se sienta cómodo con la cantidad de
+atención que le demanda la
+aplicación, por eso debe utilizarlas de forma moderada.</p>
+
+<h3 id="when_to_display_a_notification">Cuándo se deben mostrar las notificaciones</h3>
+
+<p>Para crear una aplicación que los usuarios disfruten, es importante
+reconocer que la atención
+y el enfoque del usuario son recursos que se deben proteger. Aunque el sistema de notificaciones de Android
+se diseñó
+para minimizar el impacto de las notificaciones en la atención del usuario,
+es
+importante tener en cuenta que las notificaciones interrumpen el
+flujo de tareas del usuario.
+Cuando planifique sus notificaciones, pregúntese si son lo suficiente importantes como para
+realizar una interrupción. Si no está seguro, permítale al usuario que elija las
+notificaciones mediante la configuración de notificaciones de su aplicación o que ajuste
+la marca de prioridad de las notificaciones en <code>LOW</code> o <code>MIN</code> para
+evitar distraer al usuario cuando realiza
+alguna otra tarea.</p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/TimeSensitive.png" alt="" width="311px" />
+ <p style="margin-top:10px" class="img-caption">
+ Ejemplos de notificaciones sujetas a limitación temporal
+ </p>
+
+<p>Aunque las aplicaciones más eficientes para el usuario solo proporcionan una respuesta cuando se la solicita, en algunos casos,
+vale la pena que una aplicación interrumpa al usuario con una notificación no solicitada.</p>
+
+<p>Utilice las notificaciones principalmente para <strong>eventos sujetos a limitaciones temporales</strong>, en especial
+ si estos eventos sincrónicos <strong>involucran a otras personas</strong>. Por
+ejemplo, un chat entrante
+ es una forma de comunicación sincrónica y en tiempo real: otro usuario
+está esperando de forma activa su respuesta. Los eventos del calendario son otros buenos ejemplos de cuándo se debe utilizar una
+notificación y llamar la atención del usuario,
+ ya que los eventos son inminentes y, generalmente,
+involucran a otras personas.</p>
+
+<h3 style="clear:both" id="when_not_to_display_a_notification">Cuándo no se debe
+mostrar una notificación</h3>
+
+<div class="figure" style="margin-top:60px">
+ <img src="{@docRoot}images/android-5.0/notifications/AntiSample1.png" alt="" width="311px" />
+</div>
+
+<p>En muchos otros casos, no es apropiado enviar notificaciones:</p>
+
+<ul>
+ <li> Evite notificarle al usuario acerca de información que no le enviaron
+específicamente a él o
+información que no está verdaderamente sujeta a una limitación temporal. Por ejemplo, las actualizaciones asíncronas
+e indirectas
+ que circulan por las redes sociales generalmente no justifican una interrupción en
+tiempo real. En el caso de los usuarios
+ interesados en dichas notificaciones, permítales elegir.</li>
+ <li> No cree una notificación si la información nueva y relevante se muestra actualmente
+en la pantalla. En su lugar,
+ utilice la IU de la aplicación para notificarle al usuario sobre la nueva información
+directamente en contexto.
+ Por ejemplo, una aplicación de chat no debe crear notificaciones del sistema mientras
+el usuario está chateando de forma activa con otro usuario.</li>
+ <li> No interrumpa al usuario para que ejecute operaciones técnicas de bajo nivel, como guardar
+o sincronizar información, o actualizar una aplicación si dicha aplicación o el sistema pueden resolver el problema
+sin la participación del usuario.</li>
+ <li> No interrumpa al usuario para informarle sobre un error si la
+aplicación puede solucionar el error por sus propios medios, sin que el usuario
+realice ninguna acción.</li>
+ <li> No cree notificaciones que no incluyan contenidos reales de notificación y que
+simplemente promocionen
+ su aplicación. Una notificación debe proporcionar información nueva, útil y oportuna, y
+no debe utilizarse
+ solo para lanzar una aplicación.</li>
+ <li> No cree notificaciones superfluas solo para mostrar su marca
+a los usuarios.
+ Dichas notificaciones frustran y aíslan a su público. La
+mejor forma de proporcionar
+ pequeñas cantidades de información actualizada y de mantener a los usuarios interesados
+en su
+ aplicación es desarrollar un widget que puedan colocar en la
+pantalla de inicio, si así lo desean.</li>
+</ul>
+
+<h2 style="clear:left" id="interacting_with_notifications">Interacción con
+las notificaciones</h2>
+
+<p>Las notificaciones se indican mediante iconos en la barra de estado, y se puede acceder a ellas
+al abrir el
+panel lateral de notificaciones.</p>
+
+<p>Al tocar una notificación, se abre la aplicación asociada con el contenido detallado
+que coincide con el de la notificación.
+Si dicha notificación se desplaza hacia la izquierda o la derecha, esta se eliminará del panel lateral.</p>
+
+<h3 id="ongoing_notifications">Notificaciones constantes</h3>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/MusicPlayback.png" alt="" width="311px" />
+ <p class="img-caption">
+ Notificaciones constantes relacionadas con la reproducción de música
+ </p>
+</div>
+<p>Mediante las notificaciones constantes, se mantiene a los usuarios informados sobre un proceso en curso en
+segundo plano.
+Por ejemplo, los reproductores de música anuncian la pista que se está reproduciendo actualmente en el
+sistema de notificaciones y
+siguen haciéndolo hasta que el usuario detiene la reproducción. Mediante las notificaciones constantes también se le pueden
+mostrar al usuario
+comentarios sobre tareas más extensas, como descargar un archivo o codificar un video. Los usuarios no podrán
+eliminar las notificaciones constantes del panel lateral de notificaciones.</p>
+
+<h3 id="ongoing_notifications">Reproducción de medios</h3>
+<p>En Android 5.0, la pantalla de bloqueo no muestra los controles de transporte para la clase
+{@link android.media.RemoteControlClient} obsoleta. Sin embargo, <em>sí</em> muestra las notificaciones, de modo que las notificaciones de reproducción de cada
+aplicación ahora son la forma principal
+en la que los usuarios controlan la reproducción desde el estado bloqueado. A través de este comportamiento, se le otorga más control
+a la aplicación sobre los
+botones que se deben mostrar, y la forma en que debe mostrarlos, al mismo tiempo que se proporciona
+al usuario una experiencia coherente, independientemente de si la pantalla está bloqueada o no.</p>
+
+<h3 style="clear:both"
+id="dialogs_and_toasts_are_for_feedback_not_notification">Diálogos
+y avisos</h3>
+
+<p>Su aplicación no debe crear un diálogo o un aviso si actualmente no se muestra en la
+pantalla. Los diálogos o los avisos se deben
+ mostrar únicamente como una respuesta inmediata a una acción que realiza el usuario
+dentro de su aplicación.
+Para obtener más información sobre cómo utilizar los diálogos y los avisos, consulte
+<a href="/design/patterns/confirming-acknowledging.html">Confirmación y reconocimiento</a>.</p>
+
+<h3>Orden y clasificación</h3>
+
+<p>Las notificaciones son noticias que, como tales, se muestran, básicamente, en
+orden cronológico inverso, prestando
+especial atención a la
+<a href="#correctly_set_and_manage_notification_priority">prioridad</a> de la notificación especificada en la aplicación.</p>
+
+<p>Las notificaciones son una parte clave de la pantalla de bloqueo y se muestran de forma prominente
+cada vez
+que se enciende la pantalla del dispositivo. El espacio en la pantalla de bloqueo es reducido, por lo que
+es sumamente importante
+que se identifiquen las notificaciones más urgentes o relevantes. Por este
+motivo, Android cuenta
+con un algoritmo de clasificación más sofisticado para las notificaciones, que tiene en cuenta lo siguiente:</p>
+
+<ul>
+ <li> La marca de tiempo y la prioridad especificada en la aplicación.</li>
+ <li> Si la notificación interrumpió al usuario recientemente con un sonido o una
+vibración. (Es decir,
+ si el teléfono emitió un sonido y el usuario desea saber "¿Qué
+pasó?", en la pantalla de bloqueo se debe
+ proporcionar una respuesta a simple vista).</li>
+ <li> Todas aquellas personas involucradas en la notificación mediante{@link android.app.Notification#EXTRA_PEOPLE}
+ y, especialmente, si son contactos preferidos.</li>
+</ul>
+
+<p>Para aprovechar aún más esta función de clasificación, enfóquese en la
+experiencia del usuario que desea
+crear, en lugar de centrarse en algún punto importante de la lista.</p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/AntiSample3.png" alt="" width="700px" />
+
+ <p class="img-caption" style="margin-top:10px">Las notificaciones de Gmail
+poseen una prioridad predeterminada, por lo que
+ normalmente clasifican los mensajes de una aplicación de mensajería instantánea como Hangouts, pero
+realizan
+ un cambio de prioridad temporal cuando ingresan nuevos mensajes.
+ </p>
+
+
+<h3>En la pantalla de bloqueo</h3>
+
+<p>Como las notificaciones son visibles en la pantalla de bloqueo, la privacidad del usuario es un aspecto
+especialmente
+importante. Por lo general, las notificaciones contienen información confidencial y
+no necesariamente deben ser visibles
+para cualquier persona que agarre el dispositivo y encienda la pantalla.</p>
+
+<ul>
+ <li> En el caso de los dispositivos que posean una pantalla de bloqueo segura (PIN, patrón o contraseña), la interface está formada por
+ partes públicas y privadas. La interfaz pública se puede mostrar en una pantalla de bloqueo segura y,
+ por ende, cualquier persona puede verla. La interfaz privada es el mundo detrás de esa pantalla de bloqueo y
+ solo se revela cuando el usuario se registra en el dispositivo.</li>
+</ul>
+
+<h3>Control del usuario sobre la información que se muestra en la pantalla de bloqueo segura</h3>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/LockScreen@2x.png" srcset="{@docRoot}images/android-5.0/notifications/LockScreen.png 1x" alt="" width="311px" />
+ <p class="img-caption">
+ Notificaciones en la pantalla de bloqueo, en la que el contenido se revela luego de que el usuario desbloquea el dispositivo
+ </p>
+</div>
+
+<p>Cuando se configura una pantalla de bloqueo segura, el usuario puede decidir ocultar los
+detalles confidenciales de dicha pantalla. En este caso, la IU del sistema
+analiza el <em>nivel de visibilidad</em> de la notificación para decidir
+qué información se puede mostrar de forma segura.</p>
+<p> Para controlar el nivel de visibilidad, realice una llamada a
+<code><a
+href="/reference/android/app/Notification.Builder.html#setVisibility(int)">Notification.Builder.setVisibility()</a></code>
+ y especifique uno de los siguientes valores:</p>
+
+<ul>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_PUBLIC">VISIBILITY_PUBLIC</a></code>.
+Se muestra todo el contenido de la notificación.
+ Esta es la opción predeterminada del sistema si no se especificó el grado de visibilidad.</li>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_PRIVATE">VISIBILITY_PRIVATE</a></code>.
+En la pantalla de bloqueo se muestra la información básica sobre la existencia de esta notificación, incluido
+el icono y el nombre de la aplicación a través de la cual se publicó. No se muestra el resto de los detalles de la notificación.
+A continuación, especificamos algunos puntos que se deben tener en cuenta:
+ <ul>
+ <li> Si desea proporcionar una versión pública diferente de su notificación
+para que el sistema la muestre en una pantalla de bloqueo segura, suministre un
+objeto de notificación de reemplazo en el campo <code><a
+href="/reference/android/app/Notification.html#publicVersion">Notification.publicVersion</a></code>
+.
+ <li> Mediante esta configuración, su aplicación puede crear una versión resumida del
+contenido que sigue siendo útil, pero que no revela información personal. Considere el ejemplo de una
+aplicación de SMS cuyas notificaciones incluyen el texto del SMS, el nombre del remitente y el icono del contacto.
+Esta notificación debe ser <code>VISIBILITY_PRIVATE</code>, pero <code>publicVersion</code> podría
+seguir conteniendo información útil como "3 mensajes nuevos", sin que se muestren otros detalles
+de identificación.
+ </ul>
+ </li>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_SECRET">Notification.VISIBILITY_SECRET</a></code>. Se muestra solo la menor cantidad de información posible; se excluye incluso
+el icono de la notificación.</li>
+</ul>
+<h2 style="clear:both" id="notifications_on_android_wear">Notificaciones en
+Android Wear</h2>
+
+<p>Las notificaciones y sus <em>acciones</em> se conectan de forma predeterminada con los dispositivos con Wear.
+Los desarrolladores pueden controlar qué notificaciones se conectan desde el
+teléfono hacia el reloj
+y viceversa. Los desarrolladores también pueden controlar qué acciones se conectan. Si
+en su aplicación se incluyen
+acciones que no se pueden realizar con una sola pulsación, oculte dichas acciones
+en su notificación para Wear
+o considere anclarlas a una aplicación de Wear. De este modo, el usuario podrá
+finalizar con la acción desde el
+reloj.</p>
+
+<h4>Conexión entre notificaciones y acciones</h4>
+
+<p>Mediante un dispositivo conectado, como un teléfono, es posible conectar las notificaciones con un dispositivo con Wear, para que las
+notificaciones se muestren allí. De modo similar, también es posible conectar acciones para que el usuario pueda ejecutarlas
+directamente desde las notificaciones en los dispositivos con Wear.</p>
+
+<p><strong>Conexión</strong></p>
+
+<ul>
+ <li> Nuevos mensajes instantáneos</li>
+ <li> Acciones de una sola pulsación como Hacer +1, Me gusta o Favorito</li>
+</ul>
+
+<img src="{@docRoot}images/android-5.0/notifications/WearBasic.png" width="156px" height="156px" alt="" />
+
+<p><strong>Sin conexión</strong></p>
+
+<ul>
+ <li> Notificaciones de podcasts que llegaron recientemente</li>
+ <li> Acciones que se asignan a funciones que no se pueden ejecutar desde el reloj</li>
+</ul>
+
+
+
+<p><h4>Acciones únicas diseñadas para Wear</h4></p>
+
+<p>Existen algunas acciones que solo puede realizar en Wear. Entre estas, se incluyen las siguientes:</p>
+
+<ul>
+ <li> listas rápidas de respuestas predeterminadas como "Vuelvo enseguida";</li>
+ <li> acciones que se abren desde el teléfono;</li>
+ <li> un "Comentario" o una acción de "Respuesta" que activa la pantalla de entrada de voz;</li>
+ <li> acciones que lanzan aplicaciones específicas de Wear.</li>
+</ul>
+
+<img src="{@docRoot}images/android-5.0/notifications/ReplyAction.png" width="156px" height="156px" alt="" />
diff --git a/docs/html-intl/intl/es/preview/api-overview.jd b/docs/html-intl/intl/es/preview/api-overview.jd
new file mode 100644
index 0000000..9f68613
--- /dev/null
+++ b/docs/html-intl/intl/es/preview/api-overview.jd
@@ -0,0 +1,521 @@
+page.title=Información general de la API
+page.keywords=preview,sdk,compatibility
+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>Contenido del documento<a href="#" onclick="hideNestedItems('#toc44',this);return false;" class="header-toggle">
+
+ <span class="more">mostrar más</span>
+ <span class="less" style="display:none">mostrar menos</span></a></h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#app-linking">Vinculación de la aplicación</a></li>
+ <li><a href="#backup">Copia de seguridad automática para aplicaciones</a></li>
+ <li><a href="#authentication">Autenticación</a>
+ <ol>
+ <li><a href="#fingerprint-authentication">Autenticación por huellas dactilares</a></li>
+ <li><a href="#confirm-credential">Confirmar credencial</a></li>
+ </ol>
+ </li>
+ <li><a href="#direct-share">Compartir de forma directa</a></li>
+ <li><a href="#voice-interactions">Interacciones de voz</a></li>
+ <li><a href="#assist">Asistencia de API</a></li>
+ <li><a href="#notifications">Notificaciones</a></li>
+ <li><a href="#bluetooth-stylus">Soporte del lápiz Bluetooth</a></li>
+ <li><a href="#ble-scanning">Exploración mejorada de Bluetooth de bajo consumo</a></li>
+ <li><a href="#hotspot">Soporte de Hotspot 2.0 versión 1</a></li>
+ <li><a href="#4K-display">Modo de pantalla 4K</a></li>
+ <li><a href="#behavior-themeable-colorstatelists">ColorStateLists para poder aplicar temas</a></li>
+ <li><a href="#audio">Características de audio</a></li>
+ <li><a href="#video">Características de video</a></li>
+ <li><a href="#camera">Características de la cámara</a>
+ <ol>
+ <li><a href="#flashlight">API para luz de flash</a></li>
+ <li><a href="#reprocessing">Reprocesamiento de la cámara</a></li>
+ </ol>
+ </li>
+ <li><a href="#afw">Características de Android for Work</a></li>
+</ol>
+
+<h2>Diferencias de las API</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">Nivel de API 22 para la versión preliminar de Android M &raquo;</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>M Developer Preview le brinda una perspectiva avanzada de la próxima versión de la plataforma Android, que ofrece nuevas características para usuarios y desarrolladores de aplicaciones.
+
+ En este documento, se brinda una introducción sobre las API más distinguidas.</p>
+
+<p>M Developer Preview está destinado a <strong>usuarios desarrolladores principiantes</strong> y <strong>evaluadores</strong>.
+ Si le interesa influenciar la dirección del marco de trabajo de Android,
+<a href="{@docRoot}preview/setup-sdk.html">pruebe M Developer Preview y</a> envíenos sus comentarios.
+
+</p>
+
+<p class="caution"><strong>Advertencia:</strong> No publique las aplicaciones que utilizan M Developer Preview en la tienda de Google Play.
+</p>
+
+<p class="note"><strong>Nota:</strong> Este documento, a menudo, hace referencia a clases y métodos que aún no cuentan con materiales de referencia disponibles en <a href="{@docRoot}">developer.android.com</a>.
+ Estos elementos de API tienen el formato {@code code style} en este documento (sin hipervínculos).
+ Para obtener la documentación preliminar de la API para estos elementos, descargue la <a href="{@docRoot}preview/download.html#docs"> referencia de la versión preliminar</a>.
+</p>
+
+<h3>Importantes cambios en los comportamientos</h3>
+
+<p>Si publicó anteriormente una aplicación para Android, tenga en cuenta que su aplicación podría verse afectada por los cambios en la plataforma.
+</p>
+
+<p>Consulte la sección <a href="behavior-changes.html">Cambios en los comportamientos</a> para obtener información detallada.</p>
+
+<h2 id="app-linking">Vinculación de la aplicación</h2>
+<p>Esta versión preliminar mejora el sistema de intentos de Android al proporcionar una vinculación más sólida de la aplicación. Esta característica le permite asociar una aplicación con un dominio web propio.
+ Según esta asociación, la plataforma puede determinar la aplicación predeterminada que se debe utilizar para controlar un vínculo web en particular y omitir el paso de pedirles a los usuarios que seleccionen una aplicación. Para aprender a implementar esta característica, consulte la sección
+<a href="{@docRoot}preview/features/app-linking.html">Vinculación de la aplicación</a>.
+
+
+
+<h2 id="backup">Copia de seguridad automática para aplicaciones</h2>
+<p>Ahora, el sistema realiza restauraciones y copias de seguridad de datos completas y automáticas para las aplicaciones. Este comportamiento se habilita de forma predeterminada para las aplicaciones que tienen como destino la versión preliminar de Android M; usted no necesita agregar ningún código adicional.
+ Si los usuarios eliminan sus cuentas de Google, también se eliminarán sus datos de copias de seguridad.
+ Para obtener información sobre cómo funciona esta característica y cómo configurar qué elementos incluir en la copia de seguridad del sistema de archivo, consulte la sección
+<a href="{@docRoot}preview/backup/index.html">Copia de seguridad automática para aplicaciones</a>.
+</p>
+
+<h2 id="authentication">Autenticación</h2>
+<p>Esta versión preliminar ofrece nuevas API para permitirle autenticar usuarios al usar escaneos de huellas dactilares en los dispositivos compatibles y verificar cuán reciente es la última autenticación del usuario al utilizar un mecanismo de desbloqueo de dispositivos (como una contraseña de pantalla de bloqueo).
+
+ Use estas API junto con el <a href="{@docRoot}training/articles/keystore.html">sistema Android Keystore</a>.
+</p>
+
+<h3 id="fingerprint-authentication">Autenticación por huellas dactilares</h3>
+
+<p>Para autenticar usuarios mediante el escaneo de huellas dactilares, obtenga una instancia de la nueva clase
+{@code android.hardware.fingerprint.FingerprintManager} y llame al método
+{@code FingerprintManager.authenticate()}. Su aplicación se debe ejecutar en un dispositivo compatible con un sensor de huellas dactilares.
+ Debe implementar la interfaz de usuario para el flujo de autenticación por huellas dactilares en su aplicación y debe utilizar el ícono de huella dactilar estándar de Android en la UI. El ícono de huella dactilar de Android ({@code c_fp_40px.png}) se incluye en la
+<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">aplicación de muestra</a>. Si está desarrollando múltiples aplicaciones que utilizan la autenticación por huellas dactilares, tenga en cuenta que cada aplicación debe autenticar la huella dactilar del usuario de manera independiente.
+
+
+
+</p>
+
+<p>Para utilizar esta característica en su aplicación, primero agregue el permiso {@code USE_FINGERPRINT} en su manifiesto.
+</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>Para ver cómo una aplicación implementa la autenticación por huellas dactilares, consulte la sección
+<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">
+Ejemplo de diálogo de huella dactilar</a>.</p>
+
+<p>Si está evaluando esta característica, siga estos pasos:</p>
+<ol>
+<li>Instale la Revisión de herramientas del SDK de Android versión 24.3, si todavía no la instaló.</li>
+<li>Registre una huella dactilar nueva en el emulador; para hacerlo, vaya a
+<strong>Settings &gt; Security &gt; Fingerprint</strong>, luego siga las instrucciones de registro.</li>
+<li>Use un emulador para emular eventos táctiles de huellas dactilares con el siguiente comando.
+ Utilice el mismo comando para emular eventos táctiles de huellas dactilares en la pantalla de bloqueo o en su aplicación.
+
+<pre class="no-prettyprint">
+adb -e emu finger touch &lt;finger_id&gt;
+</pre>
+<p>En Windows, posiblemente tenga que ejecutar {@code telnet 127.0.0.1 &lt;emulator-id&gt;} seguido de
+ {@code finger touch &lt;finger_id&gt;}.
+</p>
+</li>
+</ol>
+
+<h3 id="confirm-credential">Confirmar credencial</h3>
+<p>Su aplicación puede autenticar usuarios según el tiempo que haya pasado desde que desbloquearon su dispositivo por última vez. Esta característica evita que los usuarios tengan que recordar contraseñas adicionales específicas de la aplicación y elimina la necesidad de que usted tenga que implementar su propia interfaz de usuario de autenticación.
+
+ Su aplicación debe utilizar esta característica junto con una implementación de clave pública o secreta para la autenticación del usuario.
+</p>
+
+<p>Para definir la duración del tiempo de espera en el que se puede volver a usar la misma clave después de que un usuario se haya autenticado correctamente, llame al nuevo método
+{@code android.security.keystore.KeyGenParameterSpec.setUserAuthenticationValidityDurationSeconds()}
+cuando configure {@link javax.crypto.KeyGenerator} o
+{@link java.security.KeyPairGenerator}.
+ Esta característica actualmente funciona para operaciones criptográficas simétricas.
+</p>
+
+<p>Evite mostrar el diálogo de nueva autenticación de forma excesiva: sus aplicaciones deben intentar utilizar el objeto criptográfico primero y, si se agota el tiempo de espera, deben usar el método
+{@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence) createConfirmDeviceCredentialIntent()}
+para volver a autenticar el usuario dentro de su aplicación.
+
+</p>
+
+<p>Para ver cómo la aplicación implementa esta característica, consulte la sección
+<a href="https://github.com/googlesamples/android-ConfirmCredential" class="external-link">
+Ejemplo de cómo confirmar la credencial</a>.</p>
+
+<h2 id="direct-share">Compartir de forma directa</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>Esta versión preliminar le proporciona API para que la acción de compartir sea intuitiva y rápida para los usuarios. Ahora, puede definir <em>destinos para compartir de forma directa</em> que inician una actividad específica en su aplicación. Estos destinos para compartir de forma directa se exponen a los usuarios a través del menú <em>Share</em>.
+
+ Esta característica les permite a los usuarios compartir contenido con los destinos, como contactos, dentro de otras aplicaciones.
+ Por ejemplo, el destino para compartir de forma directa podría iniciar una actividad en otra aplicación de red social, lo que le permite al usuario compartir contenido directamente con una comunidad o un amigo específicos de esa aplicación.
+
+</p>
+
+<p>Para habilitar destinos para compartir de forma directa, debe definir una clase que extienda el
+{@code android.service.} <br>
+Clase {@code chooser.ChooserTargetService}. Declare su
+{@code ChooserTargetService} en el manifiesto. En esa declaración, especifique el permiso
+{@code BIND_CHOOSER_TARGET_SERVICE} y un filtro de intento con la acción
+{@code SERVICE_INTERFACE}.</p>
+<p>El ejemplo a continuación muestra de qué manera podría declarar {@code ChooserTargetService} en su manifiesto.
+</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>Para cada actividad que desee exponer a {@code ChooserTargetService}, agregue un elemento
+{@code &lt;meta-data&gt;} con el nombre
+{@code "android.service.chooser.chooser_target_service"} en el manifiesto de su aplicación.
+</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">Interacciones de voz</h2>
+<p>
+Esta versión preliminar proporciona una nueva API de interacción de voz que, junto con las
+<a href="https://developers.google.com/voice-actions/" class="external-link">acciones de voz</a>,
+le permite compilar experiencias de conversaciones de voz en sus aplicaciones. Llame al método
+{@code android.app.Activity.isVoiceInteraction()} para determinar si su actividad se inició en respuesta a una acción de voz.
+ De ser así, su aplicación puede utilizar la clase
+{@code android.app.VoiceInteractor} para solicitar una confirmación de voz por parte del usuario, realizar una selección de una lista de opciones y mucho más.
+ Para obtener más información sobre cómo implementar acciones de voz, consulte el
+<a href="https://developers.google.com/voice-actions/interaction/" class="external-link">sitio para desarrolladores de acciones de voz</a>.
+</p>
+
+<h2 id="assist">Asistencia de API</h2>
+<p>
+Esta versión preliminar ofrece una nueva manera para que los usuarios interactúen con sus aplicaciones a través de un asistente. Si desea utilizar esta característica, el usuario debe habilitar el asistente para utilizar el contexto actual.
+ Una vez habilitado, para invocar al asistente dentro de cualquier aplicación, el usuario debe mantener presionado el botón <strong>Home</strong>.
+</p>
+<p>Su aplicación puede optar por no compartir el contexto actual con el asistente al configurar la marca
+{@link android.view.WindowManager.LayoutParams#FLAG_SECURE}. Además del conjunto de información estándar que la plataforma le pasa al asistente, su aplicación puede compartir información adicional usando la nueva clase {@code android.app.Activity.AssistContent}.
+
+</p>
+
+<p>Para proporcionarle al asistente contexto adicional desde su aplicación, siga estos pasos:</p>
+
+<ol>
+<li>Implemente la interfaz {@link android.app.Application.OnProvideAssistDataListener}.</li>
+<li>Registre esta escucha usando
+{@link android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener) registerOnProvideAssistDataListener()}.</li>
+<li>Para proporcionar información contextual específica de la actividad, invalide la devolución de llamada
+{@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()}
+y, opcionalmente, la nueva devolución de llamada {@code Activity.onProvideAssistContent()}.
+</ol>
+
+<h2 id="notifications">Notificaciones</h2>
+<p>Esta versión preliminar agrega los siguientes cambios de API para las notificaciones:</p>
+<ul>
+ <li>Nuevo nivel de filtro {@code NotificationListenerService.INTERRUPTION_FILTER_ALARMS} que corresponde al nuevo modo ocupado <em>Solo alarmas</em>.
+</li>
+ <li>Nuevo valor de categoría {@code Notification.CATEGORY_REMINDER} que se utiliza para distinguir recordatorios programados por el usuario de otros eventos
+ ({@link android.app.Notification#CATEGORY_EVENT}) y alarmas
+ ({@link android.app.Notification#CATEGORY_ALARM}).
+</li>
+ <li>Nueva clase {@code android.graphics.drawable.Icon} que se puede adjuntar a sus notificaciones a través de los métodos {@code Notification.Builder.setSmallIcon(Icon)} y
+{@code Notification.Builder.setLargeIcon(Icon)}.
+</li>
+ <li>Nuevo método {@code NotificationManager.getActiveNotifications()} que permite que sus aplicaciones descubran qué notificaciones se encuentran actualmente activas.
+ Para ver una implementación de la aplicación que utilice esta característica, consulte la sección <a href="https://github.com/googlesamples/android-ActiveNotifications" class="external-link">Ejemplo de notificaciones activas</a>.
+</li>
+</ul>
+
+<h2 id="bluetooth-stylus">Compatibilidad del lápiz Bluetooth</h2>
+<p>Esta versión preliminar ofrece soporte mejorado para las entradas de usuarios que utilizan un lápiz Bluetooth. Los usuarios pueden sincronizar y conectar un lápiz Bluetooth compatible con su teléfono o tablet.
+ Mientras está conectado, la información de posición de la pantalla táctil se fusiona con la información de los botones y la presión del lápiz para proporcionar una mayor variedad de expresiones que al utilizar la pantalla táctil solamente.
+
+ Su aplicación puede obedecer cuando se presiona el botón del lápiz y cuando se realizan acciones secundarias al registrar las nuevas devoluciones de llamadas
+{@code View.onStylusButtonPressListener} y {@code GestureDetector.OnStylusButtonPressListener}
+en su actividad.
+</p>
+
+<p>Utilice las constantes y los métodos {@link android.view.MotionEvent} para detectar las interacciones del botón del lápiz:
+</p>
+<ul>
+<li>Si el usuario toca un lápiz con un botón en la pantalla de su aplicación, el método
+{@link android.view.MotionEvent#getToolType(int) getTooltype()} devuelve
+{@link android.view.MotionEvent#TOOL_TYPE_STYLUS}.</li>
+<li>Para las aplicaciones que tienen como destino la versión preliminar de Android M, el método
+{@link android.view.MotionEvent#getButtonState() getButtonState()}
+devuelve {@code MotionEvent.STYLUS_BUTTON_PRIMARY} cuando el usuario presiona el botón principal del lápiz.
+ Si el lápiz tiene un segundo botón, el mismo método devuelve
+{@code MotionEvent.STYLUS_BUTTON_SECONDARY} cuando el usuario lo presiona. Si el usuario presiona ambos botones simultáneamente, el método devuelve ambos valores juntos separados por “OR” ({@code STYLUS_BUTTON_PRIMARY|STYLUS_BUTTON_SECONDARY}).
+
+</li>
+<li>
+Para las aplicaciones que tienen como destino una versión anterior de la plataforma, el método
+{@link android.view.MotionEvent#getButtonState() getButtonState()} devuelve
+{@link android.view.MotionEvent#BUTTON_SECONDARY} (cuando se presiona el botón principal),
+{@link android.view.MotionEvent#BUTTON_TERTIARY} (cuando se presiona el botón secundario) o ambos.
+</li>
+</ul>
+
+<h2 id="ble-scanning">Exploración mejorada de Bluetooth de bajo consumo</h2>
+<p>
+Si su aplicación realiza exploraciones de Bluetooth de bajo consumo, puede utilizar el nuevo método
+{@code android.bluetooth.le.ScanSettings.Builder.setCallbackType()} para especificar que usted desea que las devoluciones de llamadas se notifiquen solo cuando se encuentre por primera vez un paquete de anuncio que coincida con el conjunto
+{@link android.bluetooth.le.ScanFilter} y cuando no se vea durante un período determinado.
+
+ Este enfoque de exploración es más eficaz en cuanto al consumo de energía que la que se proporciona en la versión anterior de la plataforma.
+
+</p>
+
+<h2 id="hotspot">Soporte de Hotspot 2.0 versión 1</h2>
+<p>
+Esta versión preliminar agrega soporte para la especificación de Hotspot 2.0 versión 1 en los dispositivos Nexus 6 y Nexus 9. Para proveer credenciales de Hotspot 2.0 en su aplicación, use los métodos nuevos de la clase
+{@link android.net.wifi.WifiEnterpriseConfig}, como {@code setPlmn()} y
+{@code setRealm()}.
+ En el objeto {@link android.net.wifi.WifiConfiguration}, puede configurar los campos
+{@link android.net.wifi.WifiConfiguration#FQDN} y {@code providerFriendlyName}. La nueva propiedad {@code ScanResult.PasspointNetwork} indica si una red detectada representa un punto de acceso de Hotspot 2.0.
+
+
+</p>
+
+<h2 id="4K-display">Modo de pantalla 4K</h2>
+<p>Ahora, la plataforma permite que las aplicaciones soliciten que la resolución de pantalla se actualice a una representación 4K en el hardware compatible.
+ Para consultar la resolución física actual, use las nuevas API
+{@code android.view.Display.Mode}. Si la UI se establece en una resolución lógica más baja y se aumenta a una resolución física más alta, tenga en cuenta que la resolución física que devuelve el método
+{@code Display.Mode.getPhysicalWidth()} puede ser diferente de la resolución lógica informada por {@link android.view.Display#getSize(android.graphics.Point) getSize()}.
+
+</p>
+
+<p>Puede pedirle al sistema que cambie la resolución física en su aplicación mientras se ejecuta y, para ello, debe configurar la propiedad {@code WindowManager.LayoutParams.preferredDisplayModeId} de la ventana de su aplicación.
+ Esta característica resulta útil si desea cambiar a la resolución de pantalla 4K.
+ Mientras se encuentra en el modo de pantalla 4K, la UI se continúa representando en la resolución original (como 1080p) y se aumenta a 4K, pero los objetos
+{@link android.view.SurfaceView} pueden mostrar contenido en la resolución nativa.
+</p>
+
+<h2 id="behavior-themeable-colorstatelists">ColorStateLists para poder aplicar temas</h2>
+<p>Ahora, los atributos de tema se admiten en
+{@link android.content.res.ColorStateList} para los dispositivos que ejecutan la versión preliminar de Android M. Los métodos
+{@link android.content.res.Resources#getColorStateList(int) getColorStateList()} y
+{@link android.content.res.Resources#getColor(int) getColor()} se dejaron de usar. Si desea llamar a estas API, en su lugar, llame a los métodos nuevos {@code Context.getColorStateList()} o
+{@code Context.getColor()}.
+ Estos métodos también se encuentran disponibles en la biblioteca AppCompat v4 vía {@link android.support.v4.content.ContextCompat}.
+</p>
+
+<h2 id="audio">Características de audio</h2>
+
+<p>Esta versión preliminar agrega mejoras al procesamiento de audio en Android, lo que incluye lo siguiente: </p>
+<ul>
+ <li>Soporte para el protocolo <a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a>
+, con las nuevas API {@code android.media.midi}. Utilice estas API para enviar y recibir eventos MIDI.
+</li>
+ <li>Clases nuevas {@code android.media.AudioRecord.Builder} y {@code android.media.AudioTrack.Builder}
+ para crear capturas de audio digital y objetos de reproducción respectivamente, y configurar propiedades de receptores y fuentes de audio para invalidar los valores predeterminados del sistema.
+</li>
+ <li>Enlaces de API para asociar dispositivos de entrada y de audio. Esto resulta particularmente útil si su aplicación les permite a los usuarios iniciar una búsqueda por voz desde un controlador para juegos o un control remoto conectados a un TV con Android. El sistema invoca la nueva devolución de llamada {@code android.app.Activity.onSearchRequested()} cuando el usuario inicia una búsqueda.
+
+
+ Para determinar si el dispositivo de entrada del usuario tiene un micrófono incorporado, recupere el objeto {@link android.view.InputDevice} de esa devolución de llamada y luego llame al nuevo método
+{@code InputDevice.hasMic()}.
+</li>
+ <li>Nueva clase {@code android.media.AudioDevicesManager}, que le permite recuperar una lista de todos los dispositivos de audio receptores y fuente adjuntos.
+ También puede especificar un objeto
+{@code android.media.OnAudioDeviceConnectionListener} si desea que su aplicación reciba una notificación cuando se conecta o desconecta un dispositivo de audio.
+</li>
+</ul>
+
+<h2 id="video">Características de video</h2>
+<p>Esta versión preliminar agrega nuevas capacidades a las API de procesamiento de video, entre ellas, las siguientes:</p>
+<ul>
+<li>Nueva clase {@code android.media.MediaSync} que ayuda a las aplicaciones a representar de forma sincrónica transmisiones de audio y video.
+ Los búferes de audio se envían de manera que no generan bloqueo y regresan mediante una devolución de llamada.
+ Además, admite una velocidad de reproducción dinámica.
+</li>
+<li>Nuevo evento {@code MediaDrm.EVENT_SESSION_RECLAIMED}, que indica cuando una sesión abierta por la aplicación es reclamada por el administrador de recursos.
+ Si su aplicación utiliza sesiones DRM, debe controlar este evento y asegurarse de no utilizar una sesión reclamada.
+
+</li>
+<li>Nuevo código de error {@code MediaCodec.CodecException.ERROR_RECLAIMED}, que indica que el administrador de recursos reclamó el recurso multimedia utilizado por el códec.
+ Con esta excepción, se debe liberar el códec, ya que pasó al estado terminal.
+
+</li>
+<li>Nueva interfaz {@code MediaCodecInfo.CodecCapabilities.getMaxSupportedInstances()} para obtener una indicación de la cantidad máxima de instancias concurrentes de códec admitidas.
+
+</li>
+<li>Nuevo método {@code MediaPlayer.setPlaybackParams()} para configurar la velocidad de reproducción multimedia para reproducciones rápidas o lentas.
+ Además, alarga o acelera la reproducción de audio de forma automática junto con el video.
+</li>
+</ul>
+
+<h2 id="camera">Características de la cámara</h2>
+<p>Esta versión preliminar incluye las siguientes API nuevas para acceder a la luz de flash de la cámara y para el reprocesamiento de imágenes de la cámara:
+</p>
+
+<h3 id="flashlight">API para luz de flash</h3>
+<p>Si un dispositivo de cámara cuenta con una unidad de flash, puede llamar al método {@code CameraManager.setTorchMode()}
+para activar o desactivar el modo linterna de una unidad de flash sin abrir el dispositivo de cámara. La aplicación no tiene propiedad exclusiva de la unidad de flash ni del dispositivo de cámara.
+ El modo linterna se desactiva y deja de estar disponible cuando la cámara no se encuentra disponible o cuando otros recursos de la cámara que mantienen la linterna encendida dejan de estar disponibles.
+
+ Otras aplicaciones también pueden llamar a {@code setTorchMode()}
+para desactivar el modo linterna. Cuando se cierra la última aplicación que activó el modo linterna, este modo se desactiva.
+</p>
+
+<p>Si desea registrar una devolución de llamada para recibir una notificación sobre el estado del modo linterna, llame al método
+{@code CameraManager.registerTorchCallback()}. La primera vez que se registra la devolución de llamada, se llama inmediatamente con el estado del modo linterna de todos los dispositivos de cámara que se conocen actualmente y que tengan una unidad de flash.
+
+ Si el modo linterna se activa o desactiva correctamente, se invoca al método
+{@code CameraManager.TorchCallback.onTorchModeChanged()}.</p>
+
+<h3 id="reprocessing">API de reprocesamiento</h3>
+<p>La API {@link android.hardware.camera2 Camera2} se extiende para admitir el reprocesamiento de imágenes privadas de formato opaco y YUV.
+ Su aplicación determina si las capacidades de reprocesamiento se encuentran disponibles vía {@code CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES}.
+ Si un dispositivo admite el reprocesamiento, usted puede crear una sesión de captura de cámara reprocesable llamando a
+{@code CameraDevice.createReprocessableCaptureSession()} y puede crear solicitudes para el reprocesamiento de búferes de entrada.
+
+</p>
+
+<p>Utilice la clase {@code ImageWriter} para conectar el flujo del búfer de entrada a la entrada de reprocesamiento de la cámara.
+ Para obtener un búfer vacío, siga el modelo de programación que se indica a continuación:</p>
+
+<ol>
+<li>Llame al método {@code ImageWriter.dequeueInputImage()}.</li>
+<li>Complete los datos en el búfer de entrada.</li>
+<li>Envíe el búfer a la cámara llamando al método {@code ImageWriter.queueInputImage()}.</li>
+</ol>
+
+<p>Si está utilizando un objeto {@code ImageWriter} junto con una imagen
+{@code android.graphics.ImageFormat.PRIVATE}, su aplicación no puede acceder a los datos de la imagen de forma directa.
+ En cambio, pase la imagen {@code ImageFormat.PRIVATE} directamente a
+{@code ImageWriter} llamando al método {@code ImageWriter.queueInputImage()} sin ninguna copia del búfer.
+</p>
+
+<p>La clase {@code ImageReader} ahora admite secuencias de imagen de formato {@code android.graphics.ImageFormat.PRIVATE}.
+ Este soporte le permite que su aplicación mantenga una cola de imagen circular de imágenes de salida
+{@code ImageReader}, seleccione una o más imágenes y las envíe a
+{@code ImageWriter} para el reprocesamiento de la cámara.</p>
+
+<h2 id="afw">Características de Android for Work</h2>
+<p>Esta versión preliminar incluye las siguientes API nuevas para Android for Work:</p>
+<ul>
+ <li><strong>Controles mejorados para dispositivos corporativos de uso único:</strong> El propietario de dispositivo ahora puede controlar las configuraciones que se describen a continuación para mejorar la administración de los dispositivos corporativos de uso único (Corporate-Owned, Single-Use, COSU).
+
+
+ <ul>
+ <li>Deshabilitar o volver a habilitar la protección de seguridad con el método
+{@code DevicePolicyManager.setKeyguardEnabledState()}.</li>
+ <li>Deshabilitar o volver a habilitar la barra de estado (lo que incluye configuraciones rápidas, notificaciones y el gesto de navegación al deslizar el dedo hacia arriba para iniciar Google Now) con el método
+{@code DevicePolicyManager.setStatusBarEnabledState()}.
+</li>
+ <li>Deshabilitar o volver a habilitar el inicio seguro con la constante {@link android.os.UserManager}
+{@code DISALLOW_SAFE_BOOT}.</li>
+ <li>Evitar que se apague la pantalla mientras el dispositivo se encuentra conectado con la constante
+ {@link android.provider.Settings.Global} {@code STAY_ON_WHILE_PLUGGED_IN}.</li>
+ </ul>
+ </li>
+ <li><strong>Instalación y desinstalación automáticas de aplicaciones por parte del propietario de dispositivo:</strong> Un propietario de dispositivo ahora puede instalar y desinstalar aplicaciones de manera automática con las API {@link android.content.pm.PackageInstaller}
+, independiente de Google Play for Work.
+ Ahora, puede aprovisionar los dispositivos a través de un propietario de dispositivo que obtiene e instala aplicaciones sin interacción del usuario.
+ Esta característica es útil para habilitar el aprovisionamiento con un toque de quioscos u otros dispositivos similares sin activar una cuenta de Google.
+</li>
+<li><strong>Acceso automático al certificado de empresa:</strong> Ahora cuando una aplicación llama a
+{@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()}, antes de que se indique al usuario que seleccione un certificado, el propietario de dispositivo o perfil puede llamar al método {@code DeviceAdminReceiver.onChoosePrivateKeyAlias()} para proporcionar el alias de forma automática a la aplicación que realiza la solicitud.
+
+
+ Esta característica le permite conceder a las aplicaciones gestionadas acceso a certificados sin interacción del usuario.
+</li>
+<li><strong>Aceptación automática de actualizaciones del sistema:</strong> Al configurar una directiva de actualización del sistema con
+{@code DevicePolicyManager.setSystemUpdatePolicy()}, el propietario de dispositivo ahora puede aceptar automáticamente una actualización del sistema, por ejemplo, en el caso de un dispositivo de quiosco, o posponer la actualización y evitar que el usuario la ejecute durante un plazo de hasta 30 días.
+
+ Además, un administrador puede configurar un período de tiempo diario en el que se debe ejecutar una actualización, por ejemplo, durante las horas en que no se usa el dispositivo de quiosco.
+ Cuando hay una actualización del sistema disponible, el sistema verifica si la aplicación Work Policy Controller definió una directiva de actualización del sistema y se comporta según corresponda.
+
+
+</li>
+<li>
+<strong>Instalación delegada de certificados:</strong> Ahora, un propietario de dispositivo o perfil puede concederle a una aplicación de terceros la capacidad de llamar a estas API de administración de certificados {@link android.app.admin.DevicePolicyManager}:
+
+
+<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>Protección de restablecimiento de la configuración predeterminada de fábrica:</strong> Al aprovisionar a un propietario de dispositivo, ahora podrá configurar parámetros para desbloquear la protección de restablecimiento de la configuración predeterminada de fábrica (Factory Reset Protection, FRP) configurando el paquete
+{@code DeviceManagerPolicy.EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS}.
+ Una aplicación de Programador NFC puede proporcionar estos parámetros después del restablecimiento de un dispositivo para desbloquear la FRP y aprovisionar al dispositivo sin requerir la cuenta de Google configurada previamente.
+
+ Si no modifica estos parámetros, la FRP se conserva y evita que el dispositivo se active sin las credenciales de Google activadas previamente.
+
+
+<p>Además, al configurar las restricciones de la aplicación en los servicios de Google Play, los propietarios de dispositivos pueden especificar cuentas de Google alternativas para desbloquear la FRP y reemplazar las que se encuentran activadas en el dispositivo.
+</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>Seguimiento del uso de datos:</strong> Ahora, un propietario de dispositivo o perfil puede consultar las estadísticas de uso de datos que se pueden ver en <strong>Settings &gt; Data</strong> utilizando los nuevos métodos
+{@code android.app.usage.NetworkStatsManager}.
+ A los propietarios de perfiles se les concede automáticamente permiso para consultar los datos del perfil que administran, mientras que los propietarios de dispositivo obtienen acceso a los datos de uso del usuario principal administrado.
+
+</li>
+<li><strong>Administración de permisos de tiempo de ejecución:</strong>
+<p>Un propietario de dispositivo o perfil puede configurar una directiva de permisos para todas las solicitudes de tiempo de ejecución de todas las aplicaciones que utilizan
+{@code DevicePolicyManager.setPermissionPolicy()}, a fin de pedirle confirmación al usuario para conceder el permiso de manera normal, o bien, para conceder o negar el permiso automáticamente sin notificarlo.
+
+ Si se configura la última directiva, el usuario no puede modificar la selección realizada por el propietario de dispositivo o perfil dentro de la pantalla de permisos de la aplicación en <strong>Settings</strong>.
+
+</p></li>
+<li><strong>VPN en Settings:</strong> Las aplicaciones de la VPN (red privada virtual) ahora se pueden ver en
+<strong>Settings &gt; More &gt; VPN</strong>. Además, las notificaciones que acompañan el uso de la VPN ahora son específicas para la manera en que dicha VPN está configurada.
+
+ Para el propietario de perfil, las notificaciones son específicas dependiendo de si la VPN se configura para un perfil administrado, un perfil personal o ambos.
+ Para un propietario de dispositivo, las notificaciones son específicas dependiendo de si la VPN se configura para todo el dispositivo.
+</li>
+<li><strong>Notificación del estado del trabajo:</strong> Ahora aparecerá un ícono de maletín en la barra de estado siempre que una aplicación del perfil administrado tenga una actividad en primer plano.
+ Además, si el dispositivo se desbloquea directamente para la actividad de una aplicación del perfil administrado, se mostrará una notificación del sistema para informarle al usuario que se encuentra dentro del perfil de trabajo.
+
+
+</li>
+</ul>
+
+<p class="note">
+ Para obtener una vista detallada de todos los cambios de la API en M Developer Preview, consulte el <a href="{@docRoot}preview/download.html">Informe de diferencias de las API</a>.
+</p>
diff --git a/docs/html-intl/intl/es/preview/behavior-changes.jd b/docs/html-intl/intl/es/preview/behavior-changes.jd
new file mode 100644
index 0000000..75936bd
--- /dev/null
+++ b/docs/html-intl/intl/es/preview/behavior-changes.jd
@@ -0,0 +1,403 @@
+page.title=Cambios en los comportamientos
+page.keywords=versión preliminar,sdk,compatibilidad
+sdk.platform.apiLevel=MNC
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Contenido del documento</h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#behavior-runtime-permissions">Permisos de tiempo de ejecución</a></li>
+ <li><a href="#behavior-power">Optimizaciones de ahorro de energía</a>
+ <ol>
+ <li><a href="#behavior-doze">Doze</a></li>
+ <li><a href="#behavior-app-standby">App Standby</a></li>
+ </ol>
+ </li>
+ <li><a href="#behavior-adoptable-storage">Dispositivos de almacenamiento adoptables</a></li>
+ <li><a href="#behavior-apache-http-client">Eliminación del cliente HTTP de Apache</a></li>
+ <li><a href="#behavior-audiomanager-Changes">Cambios en AudioManager</a></li>
+ <li><a href="#behavior-test-selection">Selección de texto</a></li>
+ <li><a href="#behavior-keystore">Cambios en Android Keystore</a></li>
+ <li><a href="#behavior-network">Cambios en las funciones de red y Wi-Fi</a></li>
+ <li><a href="#behavior-camera">Cambios en el servicio de cámara</a></li>
+ <li><a href="#behavior-art-runtime">Tiempo de ejecución de ART</a></li>
+ <li><a href="#behavior-apk-validation">Validación de APK</a></li>
+ <li><a href="#behavior-afw">Cambios en Android for Work</a></li>
+</ol>
+
+<h2>Diferencias de las API</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">Nivel de API 22 para la versión preliminar de Android M &raquo;</a> </li>
+</ol>
+
+
+<h2>Consulte también</h2>
+<ol>
+<li><a href="{@docRoot}preview/api-overview.html">Información general de la API de M Developer Preview</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>Además de nuevas características y capacidades, M Developer Preview incluye diversos cambios en el sistema y cambios en los comportamientos de la API.
+ En este documento, se destacan algunos de los cambios principales que debe comprender y justificar en sus aplicaciones.
+</p>
+
+<p>Si publicó anteriormente una aplicación para Android, tenga en cuenta que su aplicación podría verse afectada por estos cambios en la plataforma.
+</p>
+
+<h2 id="behavior-runtime-permissions">Permisos de tiempo de ejecución</h1>
+<p>Esta versión preliminar introduce un nuevo modelo de permisos en el que los usuarios ahora pueden administrar directamente los permisos de la aplicación en tiempo de ejecución.
+ Este modelo les proporciona a los usuarios mayor visibilidad y control sobre los permisos y, al mismo tiempo, simplifica los procesos de instalación y actualización automática para los desarrolladores de aplicaciones. Los usuarios pueden conceder o revocar permisos de forma individual para las aplicaciones instaladas.
+
+ </p>
+
+<p>En sus aplicaciones que tienen como destino la versión preliminar de Android M, asegúrese de comprobar y solicitar los permisos en tiempo de ejecución.
+ Para determinar si se concedió un permiso a su aplicación, llame al nuevo método {@code Context.checkSelfPermission()}.
+ Para solicitar un permiso, llame al nuevo método
+{@code Activity.requestPermission()}. Incluso si su aplicación no tiene como destino la versión preliminar de Android M, debería probar su aplicación de acuerdo con el nuevo modelo de permisos.
+</p>
+
+<p>Para obtener detalles sobre la compatibilidad del nuevo modelo de permisos en su aplicación, consulte la página
+<a href="{@docRoot}preview/features/runtime-permissions.html">
+Permisos</a> de la versión preliminar para desarrolladores. Para obtener consejos sobre cómo evaluar el impacto en su aplicación, consulte la <a href="{@docRoot}preview/testing/guide.html#runtime-permissions">Guía de prueba</a>.
+</p>
+
+<h2 id="behavior-power">Optimizaciones de ahorro de energía</h2>
+<p>Esta versión preliminar introduce nuevas optimizaciones de ahorro de energía para aplicaciones y dispositivos inactivos.</p>
+
+<h3 id="behavior-doze">Doze</h3>
+<p>Si un dispositivo está desconectado y permanece quieto con la pantalla apagada durante un período determinado, pasará al modo <em>Doze</em>, en el que el dispositivo intenta mantener el sistema en estado de suspensión.
+ En este modo, los dispositivos reanudan periódicamente el funcionamiento normal durante períodos breves, de manera que la aplicación se pueda sincronizar y el sistema pueda realizar las operaciones pendientes.
+
+</p>
+
+<p>Durante el modo Doze, se aplican las siguientes restricciones a sus aplicaciones:</p>
+<ul>
+<li>Se deshabilita el acceso a la red, salvo que su aplicación reciba una señal de prioridad alta de Google Cloud Messaging (envío de mensajes a través de la nube de Google).
+</li>
+<li>Se ignoran los <a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">Wakelocks</a>.</li>
+<li>Se deshabilitan las alarmas programadas con la clase {@link android.app.AlarmManager}, salvo las alarmas que haya configurado con el método {@link android.app.AlarmManager#setAlarmClock setAlarmClock()}
+y con {@code AlarmManager.setAndAllowWhileIdle()}.
+</li>
+<li>No se realiza la detección de Wi-Fi.</li>
+<li>No se permite la ejecución de sincronizaciones ni trabajos para sus adaptadores de sincronización y {@link android.app.job.JobScheduler}.
+</li>
+</ul>
+</p>
+<p>Al salir del modo Doze, el dispositivo ejecuta los trabajos y las sincronizaciones pendientes.</p>
+<p>Para probar esta característica, conecte un dispositivo que esté ejecutando la versión preliminar de Android M a su equipo de desarrollo y llame a los siguientes comandos:
+
+</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>Nota:</strong> La próxima versión de
+<a href="https://developers.google.com/cloud-messaging/" class="external-link">
+Google Cloud Messaging</a> le permite designar mensajes de prioridad alta.
+ Si su aplicación recibe mensajes de GCM de prioridad alta, se le concede un breve acceso a la red, incluso cuando el dispositivo se encuentra en modo Doze.
+
+</p>
+
+<p>Consulte la
+<a href="{@docRoot}preview/testing/guide.html#doze-standby">Guía de prueba</a> para obtener consejos sobre cómo probar el modo Doze en su aplicación.
+ </p>
+
+<h3 id="behavior-app-standby">App Standby</h3>
+<p>Con esta versión preliminar, el sistema puede determinar que las aplicaciones se encuentran inactivas cuando no están en uso activo.
+ La aplicación se considera inactiva después de un cierto período, salvo que el sistema detecte alguna de las siguientes señales:
+</p>
+
+<ul>
+<li>El usuario inicia explícitamente la aplicación.</li>
+<li>La aplicación actualmente tiene un proceso en primer plano (ya sea como una actividad o un servicio en primer plano, o en uso por parte de otra actividad u otro servicio en primer plano).
+</li>
+<li>La aplicación genera una notificación que los usuarios ven en la pantalla de bloqueo o en la bandeja de notificaciones.
+</li>
+<li>El usuario solicita explícitamente que la aplicación esté exenta de optimizaciones mediante las <strong>Configuraciones</strong>.
+</li>
+</ul>
+
+<p>Si el dispositivo está desconectado, las aplicaciones que se consideren inactivas tendrán deshabilitado el acceso a la red y se suspenderán sus sincronizaciones y trabajos.
+ Cuando el dispositivo se conecte a un sistema de alimentación, estas aplicaciones se podrán conectar a la red y podrán ejecutar los trabajos y las sincronizaciones pendientes.
+ Si el dispositivo queda inactivo durante períodos prolongados, las aplicaciones inactivas pueden acceder a la red aproximadamente una vez al día.
+</p>
+
+<p>Para probar esta característica, conecte un dispositivo que esté ejecutando la versión preliminar de Android M a su equipo de desarrollo y llame a los siguientes comandos:
+
+</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>Nota:</strong> La próxima versión de
+<a href="https://developers.google.com/cloud-messaging/" class="external-link">
+Google Cloud Messaging</a> (GCM) le permite designar mensajes de prioridad alta.
+ Si su aplicación recibe mensajes de GCM de prioridad alta, se le concede un breve acceso a la red, incluso cuando la aplicación está inactiva.
+
+</p>
+
+<p>Consulte la
+<a href="{@docRoot}preview/testing/guide.html#doze-standby">Guía de prueba</a> para obtener consejos sobre cómo probar el modo App Standby en sus aplicaciones.
+ </p>
+
+<h2 id="behavior-adoptable-storage">Dispositivos de almacenamiento adoptables</h2>
+<p>
+Con esta versión preliminar, los usuarios pueden <em>adoptar</em> dispositivos de almacenamiento externo, como tarjetas SD. Al adoptar un dispositivo de almacenamiento externo, el dispositivo se cifra y se formatea para que actúe como un elemento de almacenamiento interno.
+ Esta característica les permite a los usuarios mover tanto las aplicaciones como los datos privados de esas aplicaciones entre dispositivos de almacenamiento.
+ Al mover aplicaciones, el sistema respeta la preferencia
+<a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code android:installLocation}</a>
+del manifiesto.
+</p>
+
+<p>Si su aplicación accede a las API o a los campos que se indican a continuación, tenga en cuenta que las rutas de archivo que devuelven se modificarán dinámicamente cuando la aplicación se mueva entre dispositivos de almacenamiento interno y externo. Al crear rutas de archivo, lo más recomendable es que siempre llame a estas API de forma dinámica. No use rutas de archivo codificadas de forma rígida ni continúe usando rutas de archivo completas que se hayan creado anteriormente.
+
+
+</p>
+
+<ul>
+<li>Métodos {@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>Campos {@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>Para depurar esta característica en la versión preliminar para desarrolladores, puede habilitar la opción de adoptar una unidad USB que esté conectada a un dispositivo Android mediante un cable USB On-The-Go (OTG) y para habilitarla puede ejecutar el siguiente comando:
+</p>
+
+<pre class="no-prettyprint">
+$ adb shell sm set-force-adoptable true
+</pre>
+
+<h2 id="behavior-apache-http-client">Eliminación del cliente HTTP de Apache</h2>
+<p>Esta versión preliminar elimina el soporte del cliente HTTP de Apache. Si su aplicación utiliza este cliente y tiene como destino Android 2.3 (API de nivel 9) o una versión posterior, use, en su lugar, la clase {@link java.net.HttpURLConnection}.
+
+ Esta API es más eficaz porque reduce el uso de la red mediante compresión y almacenamiento de respuesta en caché transparentes, y minimiza el consumo de energía.
+ Para continuar utilizando las API HTTP de Apache, primero debe declarar la siguiente dependencia en tiempo de compilación en su archivo {@code build.gradle}:
+
+</p>
+<pre>
+android {
+ useLibrary 'org.apache.http.legacy'
+}
+</pre>
+<p>Android está migrando de la biblioteca OpenSSL a
+<a href="https://boringssl.googlesource.com/boringssl/" class="external-link">BoringSSL</a>
+. Si utiliza Android NDK en su aplicación, no vincule bibliotecas criptográficas que no forman parte de la API de NDK, como {@code libcrypto.so} y {@code libssl.so}.
+ Estas bibliotecas no son API públicas y se pueden modificar o interrumpir sin aviso en todas las versiones y todos los dispositivos. Además, puede exponerse a vulnerabilidades de seguridad.
+
+ En cambio, modifique su código nativo para llamar a las API de criptografía de Java a través de JNI o para vincular estáticamente una biblioteca criptográfica de su elección.
+
+</p>
+
+<h2 id="behavior-audiomanager-Changes">Cambios en AudioManager</h2>
+<p>Ya no se admitirán las funciones de ajustar el volumen de forma directa o silenciar secuencias específicas por medio de la clase {@link android.media.AudioManager}
+. El método {@link android.media.AudioManager#setStreamSolo(int,boolean)
+setStreamSolo()} es obsoleto, por lo que debe llamar al método
+{@code AudioManager.requestAudioFocus()} en su lugar. Del mismo modo, el método
+{@link android.media.AudioManager#setStreamMute(int,boolean) setStreamMute()} es obsoleto; en su lugar, llame al método{@code AudioManager.adjustStreamVolume()} y pase los valores de dirección {@code ADJUST_MUTE} o {@code ADJUST_UNMUTE}.
+
+</p>
+
+<h2 id="behavior-test-selection">Selección de texto</h2>
+
+<img src="{@docRoot}preview/images/text-selection.gif" style="float:right; margin:0 0 20px 30px" width="360" height="640" />
+
+<p>Ahora, cuando los usuarios seleccionen texto en su aplicación, usted puede mostrar acciones de selección de texto, como
+<em>cortar</em>, <em>copiar</em> y <em>pegar</em> en una
+<a href="http://www.google.com/design/spec/patterns/selection.html#selection-text-selection" class="external-link">barra de herramientas flotante</a>. La implementación de la interacción del usuario es similar a la de la barra de acciones contextuales, como se describe en la sección
+<a href="{@docRoot}guide/topics/ui/menus.html#CABforViews">
+Habilitación del modo de acción contextual para vistas individuales</a>.
+</p>
+
+<p>Si desea implementar una barra de herramientas flotante para selección de texto, realice los siguientes cambios en sus aplicaciones existentes:
+</p>
+<ol>
+<li>En su objeto {@link android.view.View} o {@link android.app.Activity}, cambie sus llamados
+{@link android.view.ActionMode} de
+{@code startActionMode(Callback)} a {@code startActionMode(Callback, ActionMode.TYPE_FLOATING)}.</li>
+<li>Tome su implementación existente de {@code ActionMode.Callback} y, en su lugar, haga que sea extendida
+{@code ActionMode.Callback2}.</li>
+<li>Invalide el método {@code Callback2.onGetContentRect()} para proporcionar las coordenadas del objeto {@link android.graphics.Rect} de contenido (como un rectángulo de selección de texto) en la vista.
+</li>
+<li>Si el posicionamiento del rectángulo ya no es válido y este es el único elemento por invalidar, llame al método {@code ActionMode.invalidateContentRect()}.
+</li>
+</ol>
+
+<p>Si utiliza la biblioteca <a href="{@docRoot}tools/support-library/index.html">
+Android Support Library</a> versión 22.2, tenga en cuenta que las barras de herramientas flotantes no son compatibles con versiones anteriores y AppCompat toma el control de los objetos {@link android.view.ActionMode} de forma predeterminada.
+
+ Esto impide que se muestren las barras de herramientas flotantes. Para permitir la compatibilidad de
+{@link android.view.ActionMode} en
+{@link android.support.v7.app.AppCompatActivity}, llame a
+{@code android.support.v7.app.AppCompatActivity.getDelegate()}, luego llame a
+{@code android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled()} en el objeto
+{@link android.support.v7.app.AppCompatDelegate} devuelto y configure el parámetro de entrada como {@code false}.
+ Esta llamada devuelve el control de los objetos {@link android.view.ActionMode} al marco de trabajo.
+ En los dispositivos que ejecutan la versión preliminar de Android M, eso permite que el marco de trabajo admita los modos de barras de herramientas flotantes o
+{@link android.support.v7.app.ActionBar}, mientras que en los dispositivos anteriores a la versión preliminar de Android M solo se admiten los modos {@link android.support.v7.app.ActionBar}.
+</p>
+
+<h2 id="behavior-keystore">Cambios en Android Keystore</h2>
+<p>Con esta versión preliminar, el
+<a href="{@docRoot}training/articles/keystore.html">proveedor de Android Keystore</a> ya no admite DSA.
+ Aún se admite ECDSA.</p>
+
+<p>Las claves que no requieren cifrado de datos estáticos ya no se eliminarán cuando se restablezca o deshabilite la pantalla de bloqueo seguro (por ejemplo, cuando lo haga el usuario o el administrador del dispositivo).
+ Las claves que requieren el cifrado de datos estáticos se eliminarán durante estos eventos.
+</p>
+
+<h2 id="behavior-network">Cambios en las funciones de red y Wi-Fi</h2>
+
+<p>Esta versión preliminar introduce en las API de redes y Wi-Fi los siguientes cambios en los comportamientos.</p>
+<ul>
+<li>Ahora sus aplicaciones pueden cambiar el estado de los objetos {@link android.net.wifi.WifiConfiguration} solo si usted creó estos objetos.
+ Usted no puede modificar ni eliminar objetos
+{@link android.net.wifi.WifiConfiguration} creados por el usuario o por otras aplicaciones.
+</li>
+<li>
+Anteriormente, si una aplicación forzaba al dispositivo a conectarse a una red Wi-Fi específica utilizando
+{@link android.net.wifi.WifiManager#enableNetwork(int,boolean) enableNetwork()} con la configuración
+{@code disableAllOthers=true}, el dispositivo se desconectaba de otras redes, como los datos móviles.
+ En esta versión preliminar, el dispositivo ya no se desconectará de otras redes como estas. Si {@code targetSdkVersion} de su aplicación es {@code “20”} o inferior, se anclará a la red Wi-Fi seleccionada.
+
+ Si {@code targetSdkVersion} de su aplicación es {@code “21”} o posterior, use las API de redes múltiples (como
+{@link android.net.Network#openConnection(java.net.URL) openConnection()},
+{@link android.net.Network#bindSocket(java.net.Socket) bindSocket()} y el nuevo método
+{@code ConnectivityManager.bindProcessToNetwork()}) para garantizar que el tráfico de su red se envíe a la red seleccionada.
+
+</li>
+</ul>
+
+<h2 id="behavior-camera">Cambios en el servicio de cámara</h2>
+<p>En esta versión preliminar, el modelo para acceder a los recursos compartidos en el servicio de cámara se cambió del modelo de acceso anterior “por orden de llegada” a un modelo de acceso en el que se favorecen los procesos de prioridad alta.
+
+ Los cambios en el comportamiento del servicio incluyen los siguientes:</p>
+<ul>
+<li>El acceso a los recursos del subsistema de la cámara, lo que incluye abrir y configurar un dispositivo de cámara, se concede según la “prioridad” del proceso de la aplicación cliente.
+ Por lo general, los procesos de la aplicación con actividades en primer plano o visibles para el usuario, reciben una prioridad más alta, lo que hace que el uso y la adquisición de recursos de la cámara sean más dependientes.
+
+</li>
+<li>Los clientes con cámara activa para aplicaciones de menor prioridad pueden ser “expulsados” cuando una aplicación de mayor prioridad intenta utilizar la cámara.
+ En la API {@link android.hardware.Camera} obsoleta, esto hace que se llame al método
+{@link android.hardware.Camera.ErrorCallback#onError(int,android.hardware.Camera) onError()} para el cliente expulsado.
+
+ En la API {@link android.hardware.camera2 Camera2}, esto hace que se llame al método
+{@link android.hardware.camera2.CameraDevice.StateCallback#onDisconnected(android.hardware.camera2.CameraDevice) onDisconnected()}
+para el cliente expulsado.</li>
+<li>En los dispositivos con hardware de cámara correcto, distintos procesos de la aplicación pueden abrir y utilizar de forma independiente dispositivos de cámara separados al mismo tiempo.
+ Sin embargo, ahora el servicio de cámara detecta y no permite los casos de uso de procesos múltiples, donde el acceso simultáneo genera una degradación considerable del rendimiento o de las capacidades de cualquiera de los dispositivos de cámara abiertos.
+
+ Este cambio puede generar “expulsiones” de clientes de menor prioridad, incluso cuando ninguna otra aplicación esté intentando acceder directamente al mismo dispositivo de cámara.
+
+
+</li>
+<li>
+Cambiar el usuario actual provoca que se expulsen los clientes con cámara activa en las aplicaciones que pertenecen a la cuenta de usuario anterior.
+ El acceso a la cámara se limita a perfiles de usuario que pertenecen al usuario actual del dispositivo. En la práctica, esto significa que una cuenta de “invitado”, por ejemplo, no podrá abandonar los procesos en ejecución que utilicen el subsistema de la cámara cuando el usuario haya cambiado a otra cuenta.
+
+
+</li>
+</ul>
+
+<h2 id="behavior-art-runtime">Tiempo de ejecución de ART</h2>
+<p>El tiempo de ejecución de ART ahora implementa correctamente reglas de acceso para el método
+{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()}. Este cambio soluciona el problema que ocurría con Dalvik, que comprobaba las reglas de acceso incorrectamente en las versiones anteriores. Si su aplicación utiliza el método
+{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} y usted desea invalidar comprobaciones de acceso, llame al método
+{@link java.lang.reflect.Constructor#setAccessible(boolean) setAccessible()} con el parámetro de entrada configurado en {@code true}.
+
+
+
+ Si su aplicación utiliza la
+<a href="{@docRoot}tools/support-library/features.html#v7-appcompat">biblioteca AppCompat versión 7</a> o la
+<a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">biblioteca RecyclerView versión 7</a>, debe actualizar su aplicación para utilizar las versiones más recientes de estas bibliotecas.
+ De lo contrario, asegúrese de que las clases personalizadas a las que se haga referencia desde el XML estén actualizadas, de manera que se pueda acceder a sus constructores de clases.
+</p>
+
+<p>Esta versión preliminar actualiza el comportamiento del vinculador dinámico. El vinculador dinámico ahora entiende la diferencia entre {@code soname} de una biblioteca y su ruta de acceso (<a href="https://code.google.com/p/android/issues/detail?id=6670" class="external-link">
+error público 6670</a>), y ahora se implementa la búsqueda por {@code soname}.
+
+
+ Las aplicaciones que anteriormente funcionaban y que tenían entradas {@code DT_NEEDED} incorrectas (generalmente, rutas absolutas en el sistema de archivo del equipo de compilación) pueden generar error al cargarse.
+</p>
+
+<p>Ahora se implementa correctamente la marca {@code dlopen(3) RTLD_LOCAL}. Tenga en cuenta que
+{@code RTLD_LOCAL} es lo predeterminado, por lo que se verán afectadas las llamadas a {@code dlopen(3)} que no utilizaron explícitamente
+{@code RTLD_LOCAL} (salvo que su aplicación haya usado {@code RTLD_GLOBAL} explícitamente). Con
+{@code RTLD_LOCAL}, los símbolos no estarán disponibles para las bibliotecas cargadas por llamadas posteriores a
+{@code dlopen(3)} (a diferencia de lo que sucede al hacer referencia mediante entradas {@code DT_NEEDED}).</p>
+</p>
+
+<h2 id="behavior-apk-validation">Validación de APK</h2>
+<p>Ahora la plataforma realiza validaciones más estrictas de APK. El APK se considera dañado si un archivo está declarado en el manifiesto, pero no está presente en el APK en sí.
+ Si se elimina algún contenido, se debe volver a firmar el APK.
+</p>
+
+<h2 id="behavior-afw">Cambios en Android for Work</h2>
+<p>Esta versión preliminar incluye los siguientes cambios en los comportamientos para Android for Work:</p>
+<ul>
+<li><strong>Contactos de trabajo en contextos personales:</strong> Ahora, el registro de llamadas de Google Dialer muestra los contactos de trabajo cuando el usuario ve las llamadas anteriores. Si se configura {@code DevicePolicyManager.setCrossProfileCallerIdDisabled()} en {@code true}, se ocultan los contactos de perfiles de trabajo en el registro de llamadas de Google Dialer.
+
+
+ Los contactos de trabajo se pueden mostrar junto con los contactos personales en los dispositivos a través de Bluetooth solo si usted configura {@code DevicePolicyManager.setBluetoothContactSharingDisabled()} en {@code false}.
+
+ De forma predeterminada, se configura en {@code true}.
+
+</li>
+<li><strong>Eliminación de configuraciones de Wi-Fi:</strong> Las configuraciones de Wi-Fi agregadas por un propietario de perfil (por ejemplo, al llamar al método
+{@link android.net.wifi.WifiManager#addNetwork(android.net.wifi.WifiConfiguration)
+addNetwork()}) ahora se borran si se elimina ese perfil de trabajo.
+</li>
+<li><strong>Bloqueo de configuraciones de Wi-Fi:</strong> El usuario ya no puede modificar ni eliminar las configuraciones de Wi-Fi creadas por un propietario activo del dispositivo.
+ El usuario aún puede crear y modificar sus propias configuraciones de Wi-Fi, siempre que no se haya definido la constante {@link android.os.UserManager}
+{@link android.os.UserManager#DISALLOW_CONFIG_WIFI} para ese usuario.
+</li>
+<li><strong>Descarga de Work Policy Controller mediante la incorporación de una cuenta de Google:</strong> Cuando una cuenta de Google que requiere gestión a través de una aplicación de Work Policy Controller (WPC) se agrega a un dispositivo fuera de un contexto administrado, el flujo de incorporación de la cuenta ahora le pide al usuario que instale el WPC apropiado. Este comportamiento también se aplica a las cuentas agregadas mediante
+<strong>Settings &gt; Accounts</strong> en el asistente para instalación inicial del dispositivo.
+
+
+</li>
+<li><strong>Cambios en comportamientos específicos de la API DevicePolicyManager:</strong>
+Llamar al método {@link android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName,boolean) setCameraDisabled()}
+afecta la cámara solo del usuario que lo llama; llamarlo desde el perfil administrado no afecta las aplicaciones de cámara que se ejecutan en el usuario principal.
+ Asimismo, el método
+{@link android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures(android.content.ComponentName,int) setKeyguardDisabledFeatures()}
+ahora se encuentra disponible para propietarios de perfiles, además de propietarios de dispositivos. Un propietario de perfil puede configurar las siguientes restricciones de protección de seguridad:
+
+<ul>
+<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS} y
+ {@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_FINGERPRINT}, que afectan las configuraciones de protección de seguridad para el usuario primario del perfil.
+</li>
+<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}, que solo afecta las notificaciones generadas por aplicaciones en el perfil administrado.
+</li>
+</ul>
+</li>
+</ul>
diff --git a/docs/html-intl/intl/es/preview/features/runtime-permissions.jd b/docs/html-intl/intl/es/preview/features/runtime-permissions.jd
new file mode 100644
index 0000000..ce94f5b
--- /dev/null
+++ b/docs/html-intl/intl/es/preview/features/runtime-permissions.jd
@@ -0,0 +1,794 @@
+page.title=Permisos
+page.tags=previewresources, androidm
+page.keywords=permissions, runtime, preview
+page.image={@docRoot}preview/features/images/permissions_check.png
+@jd:body
+
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>Quickview</h2>
+ <ul>
+ <li>Si su aplicación tiene como destino el SDK de la versión preliminar de Android M, se solicitará a los usuarios que concedan permisos durante el tiempo de ejecución, en lugar de durante la instalación.
+</li>
+ <li>Los usuarios pueden cancelar los permisos en cualquier momento desde la pantalla Settings de la aplicación.
+</li>
+ <li>La aplicación necesita controlar los permisos cada vez que se ejecuta.
+</li>
+ </ul>
+
+ <h2>Contenido del documento</h2>
+ <ol>
+ <li><a href="#overview">Información general</a></li>
+ <li><a href="#coding">Codificación para permisos de tiempo de ejecución</a></li>
+ <li><a href="#testing">Prueba de permisos de tiempo de ejecución</a></li>
+ <li><a href="#best-practices">Mejores prácticas</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 Developer Preview introduce un nuevo modelo de permisos de la aplicación que facilita a los usuarios el proceso de instalación y actualización de aplicaciones.
+ Si una aplicación que se ejecuta en la versión preliminar de Android M es compatible con el nuevo modelo de permisos, el usuario no tiene que conceder ningún permiso al instalar o actualizar la aplicación. En su lugar, la aplicación solicitará los permisos a medida que los vaya necesitado y el sistema mostrará al usuario un diálogo en el que le solicitará los permisos necesarios.
+
+
+
+
+</p>
+
+<p>
+ Si la aplicación es compatible con el nuevo modelo de permisos, podrá instalarse y ejecutarse en los dispositivos con versiones anteriores de Android, utilizando el modelo de permisos anterior en esos dispositivos.
+
+
+</p>
+
+<h2 id="overview">
+ Información general
+</h2>
+
+<p>
+ En M Developer Preview, la plataforma introduce un nuevo modelo
+de permisos de la aplicación. A continuación, se presenta un resumen de los componentes principales de este nuevo modelo:
+</p>
+
+<ul>
+ <li>
+ <strong>Declaración de los permisos:</strong> Al igual que en las plataformas anteriores de Android, la aplicación declara todos los permisos que necesita en el manifiesto.
+
+ </li>
+
+ <li>
+ <strong>Grupos de permisos:</strong> Según su función, los permisos se dividen en
+<em>grupos de permisos</em>. Por ejemplo, el grupo de permisos
+<code>CONTACTS</code> contiene permisos para leer y escribir los contactos y la información de perfil del usuario.
+
+ </li>
+
+ <li>
+ <p><strong>Permisos limitados concedidos durante la instalación:</strong> Cuando el usuario instala o actualiza la aplicación, el sistema le concede a la aplicación todos los permisos que la aplicación solicita que corresponden a {@link
+ android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}.
+
+
+ Por ejemplo, los permisos para la alarma y los permisos de intento corresponden a {@link
+ android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}, por lo que se conceden automáticamente durante la instalación.
+
+ </p>
+
+ <p>El sistema puede concederle a la aplicación permisos de firma y de sistema, como se especifica en la sección <a href="#system-apps">Permisos de firma y de sistema de la aplicación</a>.
+
+ Al usuario <em>no</em> se le solicitará conceder ningún permiso durante la instalación.
+</p>
+ </li>
+
+ <li>
+ <strong>Solicitud de permisos al usuario durante el tiempo de ejecución:</strong> Cuando la aplicación solicita un permiso, el sistema le muestra al usuario un diálogo y luego llama a la función de devolución de llamada de la aplicación para notificarle si el permiso se otorgó.
+
+ Si el usuario concede un permiso, la aplicación recibe todos los permisos del área funcional de dicho permiso, los cuales fueron declarados en el manifiesto de la aplicación.
+
+
+ </li>
+
+</ul>
+
+<p>
+ Este modelo de permisos cambia la forma en la que la aplicación se comporta para características que requieren permisos.
+ A continuación, se presenta un resumen de las prácticas de desarrollo que debe seguir para ajustarse a este modelo:
+
+</p>
+
+<ul>
+
+ <li>
+ <strong>Siempre compruebe los permisos:</strong> Siempre que una aplicación necesite realizar una acción que requiere algún permiso, primero debe comprobar si ya tiene otorgado ese permiso.
+
+ En caso de no tenerlo, solicitará que se le otorgue ese permiso.
+
+ </li>
+
+ <li>
+ <strong>Administre la falta de permisos correctamente:</strong> Si la aplicación no recibe un permiso adecuado, deberá administrar la falla sin errores.
+
+ Por ejemplo, si se necesita el permiso solo para una característica añadida, la aplicación puede desactivar esa característica.
+ Si el permiso es fundamental para que la aplicación funcione, la aplicación podrá desactivar toda su funcionalidad e informar al usuario que se deben conceder dichos permisos.
+
+
+ </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>Figura 1</strong> Pantalla de permisos en Settings de la aplicación.
+ </p>
+ </div>
+
+ <li>
+ <strong>Los permisos son revocables:</strong> Los usuarios pueden revocar los permisos en cualquier momento.
+ Si un usuario desactiva los permisos de una aplicación, la aplicación <em>no</em> recibe ningún aviso.
+ Nuevamente, la aplicación deberá verificar que cuenta con los permisos necesarios antes de realizar cualquier acción restringida.
+
+ </li>
+</ul>
+
+<p class="note">
+ <strong>Nota:</strong> Si una aplicación tiene como destino M Developer Preview, <em>debe</em> utilizar el nuevo modelo de permisos.
+
+</p>
+
+<p>
+ A partir del lanzamiento de M Developer Preview, no todas las aplicaciones de Google implementarán por completo el nuevo modelo de permisos.
+ Google actualiza estas aplicaciones durante el transcurso de M Developer Preview para respetar adecuadamente las configuraciones de alternancia de los permisos.
+
+
+</p>
+
+<p class="note">
+ <strong>Nota:</strong> Si la aplicación cuenta con su propia superficie de API, no transmita permisos sin antes asegurarse de que el iniciador de la llamada cuente con los permisos requeridos para acceder a esa información.
+
+
+</p>
+
+<h3 id="system-apps">
+ Permisos de las aplicaciones de firma y de sistema
+</h3>
+
+<p>
+ Generalmente, cuando el usuario instala una aplicación, el sistema solo otorga a la aplicación
+{@link android.content.pm.PermissionInfo#PROTECTION_NORMAL
+ PROTECTION_NORMAL}. Sin embargo, en ciertas circunstancias, el sistema le concede a la aplicación más permisos:
+
+</p>
+
+<ul>
+ <li>Si una aplicación es parte de la imagen del sistema, la aplicación recibe automáticamente todos los permisos enumerados en el manifiesto.
+
+ </li>
+
+ <li>Si la aplicación solicita permisos en el manifiesto que corresponden a {@link
+ android.content.pm.PermissionInfo#PROTECTION_SIGNATURE PROTECTION_SIGNATURE} y la aplicación está firmada con el mismo certificado que el de la aplicación que declaró dichos permisos, el sistema le concede a la aplicación que los solicita esos permisos durante la instalación.
+
+
+
+ </li>
+</ul>
+
+<p>
+ En ambos casos, el usuario aún puede revocar los permisos en cualquier momento si accede a la pantalla <strong>Settings</strong> del sistema y selecciona <strong>Apps &gt;</strong>
+
+ <i>app_name</i> <strong>&gt; Permissions</strong>. La aplicación debe seguir controlando los permisos al momento de la ejecución y solicitarlos si fuese necesario.
+
+
+</p>
+
+<h3 id="compatibility">
+ Compatibilidad con modelos anteriores y posteriores
+</h3>
+
+<p>
+ Si una aplicación no tiene como destino M Developer Preview, la aplicación continúa utilizando el modelo de permisos anterior, incluso en dispositivos con la versión preliminar de Android M.
+ Cuando el usuario instala la aplicación, el sistema le solicita al usuario que otorgue todos los permisos enumerados en el manifiesto de la aplicación.
+
+
+</p>
+
+<p class="note">
+ <strong>Nota:</strong> En dispositivos que ejecutan M Developer Preview, el usuario puede desactivar los permisos para cualquier aplicación (incluso para aplicaciones heredadas) desde la pantalla Settings de la aplicación.
+
+ Si un usuario desactiva permisos para una aplicación heredada, el sistema desactiva las funciones correspondientes de forma automática.
+ Cuando la aplicación intenta realizar una operación que requiere ese permiso, la operación no generará necesariamente una excepción.
+
+ En su lugar, devolverá un conjunto de datos vacíos, indicará un error o, de lo contrario, mostrará un comportamiento inesperado.
+ Por ejemplo, si realiza una consulta sobre el calendario sin permisos, el método devuelve un conjunto de datos vacíos.
+
+</p>
+
+<p>
+ Si instala una aplicación que utiliza el nuevo modelo de permisos en un dispositivo que no ejecuta la versión preliminar de Android M, el sistema la trata como cualquier otra aplicación: el sistema le pide al usuario, durante la instalación, que conceda los permisos declarados.
+
+
+
+</p>
+
+<p class="note">
+ <strong>Nota:</strong> Para el lanzamiento de la versión preliminar, debe configurar la versión mínima del SDK en M Preview SDK para compilar con la versión del SDK preliminar.
+ Esto significa que no podrá probar dichas aplicaciones en plataformas anteriores durante la versión preliminar para desarrolladores.
+
+
+</p>
+
+<h3 id="perms-vs-intents">Permisos frente a intentos</h3>
+
+<p>
+ En muchas situaciones, puede elegir entre dos formas para que sus aplicaciones realicen una tarea.
+ Puede hacer que su aplicación solicite permiso para realizar la operación por sí misma.
+ De lo contrario, puede hacer que la aplicación utilice un intento para que otra aplicación realice la tarea.
+
+</p>
+
+<p>
+ Por ejemplo, supongamos que su aplicación necesita poder tomar fotografías con la cámara del dispositivo.
+ Su aplicación puede solicitar el permiso
+<code>android.permission.CAMERA</code>, lo que le permite a su aplicación acceder a la cámara directamente.
+ Entonces, su aplicación utilizará las API de la cámara para controlar la cámara y tomar una fotografía.
+ Este enfoque le otorga a su aplicación total control del proceso de fotografía y le permite incorporar la UI de la cámara en su aplicación.
+
+
+</p>
+
+<p>
+ Sin embargo, si no necesita dicho control, puede utilizar {@link
+ android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} para solicitar una imagen.
+ Cuando ejecute el intento, se le solicita al usuario que elija una aplicación de cámara (en caso de que no haya una aplicación de cámara predeterminada) y esa aplicación tomará la fotografía.
+
+ La aplicación de cámara devuelve la fotografía al método {@link
+ android.app.Activity#onActivityResult onActivityResult()} de su aplicación.
+</p>
+
+<p>
+ De manera similar, si necesita realizar una llamada telefónica, acceder a los contactos del usuario, etc., lo puede hacer creando intentos apropiados o puede solicitar los permisos e ingresar directamente a los objetos apropiados.
+
+ Cada enfoque tiene ventajas y desventajas.
+
+</p>
+
+<p>
+ Si utiliza los permisos:
+</p>
+
+<ul>
+ <li>La aplicación posee total control sobre la experiencia del usuario cuando usted realiza la operación.
+ Sin embargo, un control tan amplio complica su tarea, ya que usted deberá diseñar una UI apropiada.
+
+ </li>
+
+ <li>Se le solicita al usuario otorgar el permiso una vez, la primera vez que usted realiza la operación.
+ Luego, su aplicación puede realizar la operación sin requerir interacción adicional por parte del usuario.
+ Sin embargo, si el usuario no concede el permiso (o lo revoca luego), su aplicación queda inhabilitada para realizar la operación.
+
+
+ </li>
+</ul>
+
+<p>
+ Si utiliza un intento:
+</p>
+
+<ul>
+ <li>No debe diseñar la UI para la operación. La aplicación que controla el intento provee la UI. Sin embargo, esto significa que usted no tiene control sobre la experiencia del usuario.
+
+ El usuario podrá interactuar con una aplicación que usted no conoce.
+
+ </li>
+
+ <li>Si el usuario no tiene una aplicación predeterminada para la operación, el sistema le solicita al usuario que elija una aplicación. Si el usuario no designa un controlador predeterminado, es probable que surja un diálogo adicional cada vez que realice la operación.
+
+
+
+ </li>
+</ul>
+
+<h2 id="coding">Codificación para permisos de tiempo de ejecución</h2>
+
+<p>
+ Si su aplicación tiene como destino el nuevo M Developer Preview, deberá usar el nuevo modelo de permisos.
+ Esto significa que, además de declarar los permisos necesarios en el manifiesto, también debe comprobar si tiene los permisos de tiempo de ejecución y solicitarlos en caso de no tenerlos.
+
+
+
+</p>
+
+<h3 id="enabling">
+ Habilitar el nuevo modelo de permisos
+</h3>
+
+<p>
+ Para habilitar el nuevo modelo de permisos de M Developer Preview, configure el atributo
+<code>targetSdkVersion</code> de la aplicación en <code>"MNC"</code> y
+<code>compileSdkVersion</code> en <code>"android-MNC"</code>. Al hacerlo, se habilitan todas las características de los nuevos permisos.
+
+</p>
+
+<p>
+ Para el lanzamiento de la versión preliminar, debe establecer <code>minSdkVersion</code> en
+<code>"MNC"</code> para compilar con el SDK preliminar.
+</p>
+
+<h3 id="m-only-perm">
+ Establecer un permiso solo para la versión preliminar de Android M
+</h3>
+
+<p>
+ Puede utilizar el nuevo elemento <code>&lt;uses-permission-sdk-m&gt;</code> en el manifiesto de la aplicación para indicar que se necesita un permiso solo para M Developer Preview.
+ Si declara un permiso de esta manera, cuando la aplicación se instale en un dispositivo anterior, el sistema no le solicitará al usuario el permiso ni se lo otorgará a la aplicación. Al usar el elemento <code>&lt;uses-permission-sdk-m&gt;</code>, puede añadir nuevos permisos a las versiones actualizadas de su aplicación sin forzar a los usuarios a otorgar permisos cuando instalen la actualización.
+
+
+
+
+
+
+</p>
+
+<p>
+ Si la aplicación se ejecuta en un dispositivo con M Developer Preview,
+<code>&lt;uses-permission-sdk-m&gt;</code> se comporta al igual que
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>.
+ El sistema no le solicita al usuario que otorgue ningún permiso al instalar la aplicación y la aplicación solicita los permisos a medida que se necesiten.
+
+</p>
+
+<h3 id="prompting">
+ Solicitar permisos
+</h3>
+
+<p>
+ Si su aplicación utiliza el nuevo modelo de permisos de M Developer Preview, no se le pedirá al usuario que otorgue todos los permisos cuando la aplicación se ejecute por primera vez en un dispositivo con la versión preliminar de Android M.
+
+ En su lugar, su aplicación solicita los permisos a medida que los necesita.
+ Cuando su aplicación solicita un permiso, el sistema le muestra un diálogo al usuario.
+
+</p>
+
+<p>
+ Si su aplicación se ejecuta en un dispositivo con SDK 22 o anterior, la aplicación utiliza el modelo de permisos anterior.
+ Cuando el usuario instala la aplicación, se le solicita que otorgue todos los permisos que la aplicación requiere en su manifiesto, excepto aquellos permisos marcados con <code>&lt;uses-permission-sdk-m&gt;</code>.
+
+
+</p>
+
+<h4 id="check-platform">Controlar en qué plataforma se ejecuta la aplicación</h4>
+
+<p>
+ Este modelo de permisos es compatible solamente con dispositivos que ejecutan M Developer Preview.
+ Antes de llamar a cualquiera de estos métodos, la aplicación debe verificar en qué plataforma se está ejecutando y, para hacerlo, se controla el valor de {@link android.os.Build.VERSION#CODENAME
+ Build.VERSION.CODENAME}.
+
+ Si el dispositivo ejecuta M Developer Preview,
+{@link android.os.Build.VERSION#CODENAME CODENAME} es <code>"MNC"</code>.
+</p>
+
+<h4 id="check-for-permission">Controlar si la aplicación cuenta con los permisos necesarios</h4>
+
+<p>Cuando el usuario intenta realizar algo que requiere un permiso, la aplicación controla si ya tiene el permiso para realizar esa operación.
+ Para hacerlo, la aplicación llama a <code>Context.checkSelfPermission(
+
+<i>permission_name</i>)</code>. La aplicación debe realizar este control incluso si sabe que el usuario ya ha concedido ese permiso, ya que el usuario puede revocar los permisos de una aplicación en cualquier momento.
+
+
+ Por ejemplo, si un usuario quiere usar una aplicación para tomar una fotografía, la aplicación llama a <code>Context.checkSelfPermission(Manifest.permission.CAMERA)</code>.
+
+</p>
+
+<p class="table-caption" id="permission-groups">
+ <strong>Tabla 1.</strong> Permisos y grupo de permisos.</p>
+<table>
+ <tr>
+ <th scope="col">Grupo de permisos</th>
+ <th scope="col">Permisos</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">Solicitar permisos si se necesitan</h4>
+
+<p>Si la aplicación no posee los permisos que necesita, llama al método
+<code>Activity.requestPermissions(String[], int)</code> para solicitar el permiso o los permisos apropiados.
+ La aplicación pasa el permiso o los permisos que necesita y un “código de solicitud” entero.
+
+ Este método funciona de manera asincrónica: realiza la devolución inmediatamente y cuando el usuario responde a la ventana de diálogo, el sistema llama al método de devolución de llamada de la aplicación con los resultados, y pasa el mismo “código de solicitud” que pasó la aplicación a
+<code>requestPermissions()</code>.
+
+</p>
+
+ <p>El siguiente código verifica si la aplicación tiene permisos para leer los contactos del usuario y solicita los permisos de ser necesario:
+</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">Administrar la respuesta a la solicitud de permisos</h4>
+
+<p>
+ Cuando una aplicación solicita permisos, el sistema le muestra al usuario una ventana de diálogo.
+ Cuando el usuario responde, el sistema invoca
+<code>Activity.onRequestPermissionsResult(int, String[], int[])</code>
+ de su aplicación y le transfiere la respuesta del usuario. Su aplicación necesita invalidar ese método. La devolución de llamada pasa el mismo código de solicitud que usted pasó a <code>requestPermissions()</code>.
+
+ Por ejemplo, si una aplicación solicita acceso <code>READ_CONTACTS</code>, es posible que tenga el siguiente método de devolución de llamada:
+
+
+</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>Si el usuario concede un permiso, el sistema le otorga a la aplicación todos los permisos enumerados en el manifiesto para esa área funcional.
+ Se deben tomar acciones apropiadas si el usuario rechaza la solicitud.
+ Por ejemplo, usted podría desactivar cualquier acción del menú que dependa de este permiso.
+
+ </li>
+</p>
+
+<p>
+ Cuando el sistema le solicita al usuario que otorgue un permiso, el usuario tiene la opción de indicarle al sistema que no solicite ese permiso de nuevo.
+ En ese caso, cuando la aplicación utiliza <code>requestPermissions()</code> para solicitar ese permiso, el sistema rechaza la solicitud inmediatamente.
+
+ En este caso, el sistema llama a su <code>onRequestPermissionsResult()</code> de la misma manera en que lo haría si el usuario hubiese rechazado explícitamente su solicitud nuevamente.
+
+ Por esta razón, su aplicación no puede asumir que se ha llevado a cabo algún tipo de interacción con el usuario.
+
+</p>
+
+<h2 id="testing">Prueba de permisos de tiempo de ejecución</h2>
+
+
+<p>
+ Si su aplicación tiene como destino M Developer Preview, debe probar que administre los permisos correctamente.
+ No debe asumir que su aplicación tiene algún permiso en particular cuando se ejecuta.
+ Cuando la aplicación se ejecuta por primera vez, es muy probable que no tenga permisos y el usuario puede revocar o reestablecer los permisos en cualquier momento.
+
+
+</p>
+
+<p>
+ Debe probar su aplicación para asegurarse de que funciona correctamente en todas las situaciones de permisos.
+ Con el SDK de la versión preliminar de Android M, hemos brindado nuevos comandos <a href="{@docRoot}tools/help/adb.html">Android Debug Bridge (adb)</a> que le permitirán probar su aplicación con cualquier configuración de permisos que necesite probar.
+
+
+
+</p>
+
+<h3>
+ Nuevas opciones y comandos adb
+</h3>
+
+<p>
+ Las herramientas de plataforma del SDK de la versión preliminar de Android M contienen varios comandos nuevos que le permiten probar la manera en que su aplicación administra los permisos.
+
+</p>
+
+<h4>
+ Instalar con permisos
+</h4>
+
+<p>
+ Puede utilizar la nueva opción <code>-g</code> del comando <a href="{@docRoot}tools/help/adb.html#move"><code>adb
+ install</code></a>, que instala la aplicación y concede todos los permisos enumerados en el manifiesto de la aplicación:
+
+</p>
+
+<pre class="no-pretty-print">
+$ adb install -g &lt;path_to_apk&gt;
+</pre>
+
+<h4>
+ Conceder y revocar permisos
+</h4>
+
+<p>
+ Puede utilizar los comandos ADB nuevos <a href="{@docRoot}tools/help/adb.html#pm">package manager (pm)</a> para conceder y revocar permisos a una aplicación instalada. Esta funcionalidad puede resultar útil para pruebas automáticas.
+
+
+</p>
+
+<p>
+ Para conceder un permiso, utilice el comando <code>grant</code> de package manager:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant &lt;package_name&gt; &lt;permission_name&gt;
+</pre>
+
+<p>
+ Por ejemplo, para conceder el paquete de permisos com.example.myapp para grabar audio utilice este comando:
+
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO
+</pre>
+
+<p>
+ Para revocar un permiso, utilice el comando <code>revoke</code> de package manager:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm revoke &lt;package_name&gt; &lt;permission_name&gt;
+</pre>
+
+<h2 id="best-practices">Mejores prácticas</h2>
+
+<p>
+ El nuevo modelo de permisos brinda a los usuarios una experiencia más fluida y les facilita la instalación de aplicaciones, además de hacerlos sentir cómodos con las actividades de sus aplicaciones.
+
+ Sugerimos las siguientes mejores prácticas para obtener el mayor beneficio del nuevo modelo.
+
+</p>
+
+
+<h3 id="bp-what-you-need">Solicite solo los permisos que necesite</h3>
+
+<p>
+ Cada vez que solicite un permiso, usted obliga al usuario a tomar una decisión.
+ La funcionalidad de su aplicación se verá reducida si el usuario rechaza la solicitud.
+ Debe minimizar la cantidad de veces que realiza estas solicitudes.
+</p>
+
+<p>
+ Por ejemplo, a menudo, su aplicación puede obtener la funcionalidad necesaria a través de un <a href="{@docRoot}guide/components/intents-filters.html">intento</a> en lugar de una solicitud de permiso.
+
+ Si su aplicación necesita tomar fotografías con la cámara del teléfono, la aplicación puede utilizar un intento {@link
+ android.provider.MediaStore#ACTION_IMAGE_CAPTURE
+ MediaStore.ACTION_IMAGE_CAPTURE}.
+ Cuando su aplicación ejecuta el intento, el sistema le solicita al usuario que elija una aplicación para la cámara que ya está instalada a fin de tomar la fotografía.
+
+
+</p>
+
+<h3 id="bp-dont-overwhelm">
+ No abrume al usuario
+</h3>
+
+<p>
+ Si expone al usuario a muchas solicitudes de permisos al mismo tiempo, lo abrumará y hará que deje de usar su aplicación. Por el contrario, debe pedir permisos en la medida que los necesite.
+
+
+</p>
+
+<p>
+ A veces, uno o más permisos pueden ser absolutamente necesarios para la aplicación. En ese caso, es recomendable pedir todos los permisos no bien se inicie la aplicación.
+
+ Por ejemplo, si crea una aplicación de fotografía, la aplicación necesitará acceso a la cámara del dispositivo.
+ Cuando el usuario inicie la aplicación por primera vez, no se sorprenderá si la aplicación le solicita permiso para usar la cámara.
+
+ Sin embargo, si la misma aplicación además tuviese una característica para compartir fotografías con los contactos del usuario, <em>no</em> solicite ese permiso la primera vez que se ejecute.
+
+ En su lugar, espere hasta que el usuario utilice la característica “compartir” para solicitar el permiso en ese momento.
+
+</p>
+
+<p>
+ Si su aplicación proporciona un tutorial, se recomienda que se pidan los permisos esenciales de la aplicación al final del tutorial.
+
+</p>
+
+<h3 id="bp-explain">
+ Explique por qué se necesitan los permisos
+</h3>
+
+<p>
+ El diálogo de permisos que muestra el sistema cuando llama a
+ <code>requestPermissions()</code> informa qué permisos necesita su aplicación pero no establece el motivo.
+ A veces, el usuario puede confundirse.
+ Es una buena idea explicarle al usuario los motivos por los que la aplicación necesita esos permisos antes de llamar a <code>requestPermissions()</code>.
+
+</p>
+
+<p>
+ Por ejemplo, una aplicación de fotografía puede solicitar servicios de ubicación para añadir una etiqueta geográfica a las fotografías.
+ Es posible que un usuario típico no sepa que una fotografía puede contener información sobre la ubicación y se confundiría si una aplicación de fotografía solicita la ubicación.
+
+ En este caso, es recomendable que la aplicación le informe al usuario acerca de esta característica <em>antes</em> de llamar a
+<code>requestPermissions()</code>.
+
+</p>
+
+<p>
+ Una forma de hacerlo es incorporar estas solicitudes en el tutorial de la aplicación. El tutorial puede mostrar todas las características de la aplicación, una por vez, y mientras lo hace explicar los permisos que son necesarios.
+
+ Por ejemplo, el tutorial de la aplicación de fotografía puede mostrar la característica “compartir fotografías con contactos” y luego explicarle al usuario que debe otorgar permisos para que la aplicación vea los contactos del usuario.
+
+
+ La aplicación puede entonces llamar a <code>requestPermissions()</code> para solicitarle al usuario ese acceso.
+ Por supuesto, no todos los usuarios siguen el tutorial, por lo que aun así debe controlar y solicitar los permisos durante el funcionamiento normal de la aplicación.
+
+
+</p>
diff --git a/docs/html-intl/intl/es/preview/overview.jd b/docs/html-intl/intl/es/preview/overview.jd
new file mode 100644
index 0000000..49cc3d3
--- /dev/null
+++ b/docs/html-intl/intl/es/preview/overview.jd
@@ -0,0 +1,362 @@
+page.title=Información general del programa
+page.metaDescription=Bienvenido a Android M Developer Preview, el programa que le brinda todo lo que necesita para probar y optimizar sus aplicaciones para la próxima versión de Android.
+page.image=images/cards/card-preview_16-9_2x.png
+page.tags="preview", "developer", "android"
+
+@jd:body
+
+<p>
+ Bienvenido a <strong>Android M Developer Preview</strong>, el programa que le brinda todo lo que necesita para probar y optimizar sus aplicaciones para la próxima versión de Android.
+
+ Es gratis y puede comenzar a utilizarlo ahora mismo. Solo tiene que descargar las herramientas de M Developer Preview.
+
+</p>
+
+<div style="background-color:#eceff1;padding:1em;">
+<div class="wrap">
+ <div class="cols">
+ <div class="col-4of12">
+ <h5>
+ Imágenes del sistema emulador y de hardware
+ </h5>
+
+ <p>
+ Ejecute y pruebe sus aplicaciones en Nexus 5, 6, 9 y Player (para TV), además del emulador.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Último código de la plataforma
+ </h5>
+
+ <p>
+ Durante la versión preliminar, ofreceremos múltiples actualizaciones, por lo que usted realizará la prueba comparando los últimos cambios de la plataforma.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Actualizaciones vía OTA
+ </h5>
+
+ <p>
+ Luego de actualizar su dispositivo a la versión preliminar inicial, usted podrá obtener actualizaciones por red inalámbrica (over-the-air, OTA).
+
+ </p>
+ </div>
+ </div>
+
+ <div class="cols">
+
+
+ <div class="col-4of12">
+ <h5>
+ Nuevos comportamientos y capacidades
+ </h5>
+
+ <p>
+ Inicie el funcionamiento con anticipación para admitir los comportamientos de la nueva plataforma como el nuevo modelo de permisos de tiempos de ejecución y las opciones de ahorro de energía.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Ventana de prioridad para los problemas informados por los desarrolladores
+ </h5>
+
+ <p>
+ Durante las primeras semanas, daremos prioridad a los problemas informados por los desarrolladores; por lo tanto, realice las pruebas y envíe sus comentarios lo antes posible.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Comentarios y soporte
+ </h5>
+
+ <p>
+ Infórmenos los problemas y envíenos comentarios a través de nuestro <a href="https://code.google.com/p/android-developer-preview/">seguimiento de problemas</a>.
+ Póngase en contacto con otros desarrolladores de la comunidad <a href="http://g.co/dev/AndroidMDevPreview">M&nbsp;Developer Community</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">
+ Escala de tiempo y actualizaciones
+</h2>
+<img src="{@docRoot}preview/images/m-preview-timeline-crop.png" alt="Preview program timeline" id="timeline">
+<p>
+ M Developer Preview estará disponible a partir del 28 de mayo hasta la versión final del SDK de Android M, que lanzaremos al poco tiempo del lanzamiento público durante el tercer trimestre de 2015.
+
+
+</p>
+
+<p>
+ En momentos clave del desarrollo, lanzaremos actualizaciones para sus dispositivos de prueba.
+ Los momentos clave tentativos son los siguientes:
+</p>
+
+<ul>
+ <li>
+ <strong>Preview&nbsp;1</strong> (lanzamiento inicial de la versión preliminar, fines de mayo)
+ </li>
+
+ <li>
+ <strong>Preview&nbsp;2</strong> (fines de junio, comienzos de julio)
+ </li>
+
+ <li>
+ <strong>Preview&nbsp;3</strong> (casi la versión final, a fines de julio)
+ </li>
+</ul>
+
+<p>
+ Estas actualizaciones terminan con el <strong>SDK final</strong> (más adelante durante el tercer trimestre), lo que proporcionará tanto las API oficiales para la nueva versión de Android como los comportamientos y las características finales del sistema.
+
+
+</p>
+
+<p>
+ A medida que usted prueba y desarrolla en Android M, le recomendamos que <strong>mantenga su entorno de desarrollo actualizado</strong> a medida que se lanzan las actualizaciones de la versión preliminar.
+
+ Para que el proceso sea más fácil, lanzaremos <strong>actualizaciones OTA</strong> para los dispositivos que ya hayan sido actualizados a una compilación de la versión preliminar y brindaremos imágenes del sistema que puede descargar y actualizar manualmente.
+
+
+</p>
+<p class="note">
+ <strong>Nota:</strong> El SDK final y las imágenes del sistema no se pueden proporcionar vía OTA y deberán <strong>actualizarse manualmente</strong> en sus dispositivos de prueba.</strong>
+
+
+</p>
+
+<p>
+ Le informaremos cuando las actualizaciones de la versión preliminar se encuentren disponibles a través del blog de Android para desarrolladores (<a href="http://android-developers.blogspot.com/">Android Developers Blog</a>), de este sitio y de la comunidad de desarrolladores <a href="http://g.co/dev/AndroidMDevPreview">Android M Developer Community</a>.
+
+
+</p>
+
+<h2 id="preview_tools">
+ ¿Qué ofrece la versión preliminar?
+</h2>
+
+<p>
+ M Developer Preview incluye todo lo que necesita para probar sus aplicaciones actuales en una variedad de tamaños de pantalla, de tecnologías de redes, de conjuntos de chip CPU/GPU y de arquitecturas de hardware.
+
+
+</p>
+
+<h4>
+ Herramientas del SDK
+</h4>
+
+<p>
+ Estos componentes se pueden descargar mediante SDK Manager en <a href="{@docRoot}sdk/installing/adding-packages.html">Android Studio</a>:
+</p>
+
+<ul>
+ <li><strong>Herramientas del SDK</strong> de M Developer Preview
+ </li>
+
+ <li><strong>Imagen del sistema emulador</strong> (32-bit y 64-bit) de M Developer Preview
+
+ </li>
+
+ <li><strong>Imagen del sistema emulador para Android TV</strong> (32-bit) de M Developer Preview
+
+ </li>
+</ul>
+
+<h4>
+ Imágenes del sistema de hardware
+</h4>
+
+<p>
+ Puede descargar estas imágenes del sistema de hardware para dispositivos Nexus desde la <a href="download.html">página de Descargas</a>:
+
+</p>
+
+<ul>
+ <li>
+ <strong>Nexus 5</strong> (GSM/LTE) imagen del sistema del dispositivo “hammerhead”
+ </li>
+
+ <li>
+ <strong>Nexus 6</strong> imagen del sistema del dispositivo “shamu”
+ </li>
+
+ <li>
+ <strong>Nexus 9</strong> (Wi-Fi) imagen del sistema del dispositivo “volantis”
+ </li>
+
+ <li>
+ <strong>Nexus Player</strong> (Android TV) imagen del sistema del dispositivo “fugu”
+ </li>
+</ul>
+
+<h4>
+ Documentación y código de muestra
+</h4>
+
+<p>
+ Estos recursos de documentación lo ayudan a obtener información sobre la versión preliminar:
+</p>
+
+<ul>
+ <li>
+ <a href="setup-sdk.html">Configurar el SDK</a>: contiene instrucciones paso a paso para comenzar.
+
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/testing/guide.html">Guía de prueba</a> y <a href="behavior-changes.html">Cambios en los comportamientos</a>: le indican las áreas más importantes que debe probar.
+ </li>
+
+ <li>Documentación sobre las nuevas API, lo que incluye <a href="api-overview.html">Información general de la API</a>, <a href="{@docRoot}preview/download.html#docs">Referencia de la API</a> que se puede descargar y guías detalladas para desarrolladores sobre características clave como <a href="{@docRoot}preview/features/runtime-permissions.html">permisos</a>, <a href="{@docRoot}preview/backup/index.html">copias de seguridad de la aplicación</a>, entre otras.
+
+
+
+
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/samples.html">Código de ejemplo</a>: indica cómo admitir permisos y otras características nuevas.
+
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/support.html#release-notes">Notas de la versión</a> para la versión actual de M Developer Preview, lo que incluye notas sobre los cambios e informes de diferencias.
+
+ </li>
+</ul>
+
+<h4>
+ Recursos de soporte
+</h4>
+
+<p>
+ Utilice los siguientes recursos de soporte durante el proceso de prueba y desarrollo en M Developer Preview:
+
+</p>
+
+<ul>
+ <li><a href="https://code.google.com/p/android-developer-preview/">El seguimiento de problemas de M Developer Preview</a> es su<strong> canal principal de comentarios.</strong>
+
+ A través de este seguimiento de problemas, usted puede informarnos errores o problemas de rendimiento, y enviarnos comentarios generales.
+ También puede buscar <a href="https://code.google.com/p/android-developer-preview/wiki/KnownIssues">problemas recurrentes</a> y encontrar soluciones alternativas detalladas.
+
+ </li>
+
+ <li><a href="http://g.co/dev/AndroidMDevPreview">Android M Developer Community</a> es una comunidad en Google+ donde usted puede <strong>contactarse con otros desarrolladores</strong> que estén trabajando con Android M. Puede compartir comentarios o ideas, o encontrar respuestas a sus dudas sobre Android M.
+
+
+
+ </li>
+</ul>
+
+
+<h2 id="preview_apis_and_publishing">
+ Selección del destino, API preliminares y publicación
+</h2>
+
+<p>
+ Android M Developer Preview es una versión solo para desarrollo y <strong>no tiene un nivel de API estándar</strong>.
+ Si quiere darse de baja de los comportamientos de compatibilidad para probar su aplicación (lo que es muy recomendado), puede elegir como destino M Developer Preview estableciendo <code><a href=
+ "/guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a></code> de su aplicación como <code>“MNC”</code>.
+
+
+
+</p>
+
+<p>
+ Android M Developer Preview ofrece <strong>API preliminares</strong>
+ &mdash; las API no serán oficiales hasta que se lance el SDK final, lo que actualmente está planeado para el tercer trimestre de 2015.
+ Esto quiere decir que surgirán <strong>cambios menores en la API</strong> con el tiempo, particularmente durante las primeras semanas del programa.
+
+ Con cada actualización de Android M Developer Preview, proporcionaremos un resumen con los cambios realizados.
+
+</p>
+
+<p class="note">
+ Tenga en cuenta que aunque las API preliminares pueden modificarse, los comportamientos del sistema subyacente, como los permisos de tiempo de ejecución y las opciones de ahorro de energía, se mantienen estables y disponibles para cualquier prueba inmediata.
+
+
+</p>
+
+<p>
+ En cuanto a la publicación, Google Play <strong>no permite que se publiquen aplicaciones que tienen como destino M Developer Preview</strong>.
+ Una vez que el SDK final de Android M esté disponible, podrá seleccionar como destino el nivel de API oficial de Android M y publicar su aplicación en Google Play.
+
+ Mientras tanto, si desea distribuir una aplicación con Android M como destino a otros evaluadores, lo puede hacer por correo electrónico o mediante descarga directa desde su sitio.
+
+
+</p>
+
+<h2 id="get_started">
+ ¿Cómo comenzar?
+</h2>
+
+<p>
+ Para comenzar a probar su aplicación:
+</p>
+
+<ol>
+ <li>Revise el artículo <a href="{@docRoot}preview/api-overview.html">Información general de la API</a> y <a href="{@docRoot}preview/behavior-changes.html">Cambios en los comportamientos</a> para obtener una idea sobre las novedades y cómo estas pueden afectar sus aplicaciones.
+
+ En especial, infórmese sobre el nuevo modelo de <a href="{@docRoot}preview/features/runtime-permissions.html">permisos de tiempo de ejecución</a>, las opciones de ahorro de energía y las copias de seguridad automáticas.
+
+
+ </li>
+
+ <li>Configure su entorno siguiendo las instrucciones para <a href="{@docRoot}preview/setup-sdk.html">Configurar el SDK de la versión preliminar</a> y configurar los dispositivos de prueba.
+
+
+ </li>
+
+ <li>Siga las <a href="https://developers.google.com/android/nexus/images">instrucciones de actualización</a> para actualizar la última imagen del sistema del desarrollador de Android M para Nexus 5, 6, 9 y Player.
+
+ Cuando haya actualizado su dispositivo de desarrollo, recibirá las actualizaciones de la versión preliminar mediante actualizaciones OTA.</a>
+
+ </li>
+
+ <li>Descargue la <a href="{@docRoot}preview/download.html#docs">Referencia de la API de M Preview</a> y los <a href="{@docRoot}preview/samples.html">Ejemplos de M Preview</a> para obtener más información sobre las nuevas características de la API y sobre cómo utilizarlas en su aplicación.
+
+
+
+ </li>
+
+ <li>Únase a la comunidad <a href="http://g.co/dev/AndroidMDevPreview">Android M Developer Community</a> para recibir las últimas noticias y para contactarse con otros desarrolladores que estén trabajando con la nueva plataforma.
+
+
+ </li>
+</ol>
+
+<p>
+ ¡Agradecemos su participación en el programa Android M Developer Preview!
+</p>
diff --git a/docs/html-intl/intl/ja/design/get-started/principles.jd b/docs/html-intl/intl/ja/design/get-started/principles.jd
new file mode 100644
index 0000000..8e4149d
--- /dev/null
+++ b/docs/html-intl/intl/ja/design/get-started/principles.jd
@@ -0,0 +1,307 @@
+page.title=Android デザイン指針
+@jd:body
+
+<p>このデザイン指針は、ユーザーがもっとも知りたいと思われることを中心に、Android User Experience Team により、またその活動を統一的なものにするために作成されたものです。Android デベロッパーとデザイナーに対しては各種端末向けのより詳細なデザイン ガイドラインがあります。
+
+
+
+</p>
+
+<p>
+ご自身の創造性やデザインについて考える際、この指針を考慮に入れてください。
+何を当てはめるかは目的に応じて調整してください。
+</p>
+
+<h2 id="enchant-me">ユーザーを引きつける</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="delight-me">サプライズで楽しませる</h4>
+<p>美しい画面、考え抜かれて配置されたアニメーション、タイミングの良いサウンド エフェクトは、使っていて楽しくなります。
+わずかな効果でも、ユーザーを楽しませ、力を得たように感じてもらえます。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_delight.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="real-objects-more-fun">ボタンやメニューよりもリアルなオブジェクトでさらに楽しく</h4>
+<p>ユーザーがアプリでオブジェクトを直接タップしたり操作したりできるようになります。タスクを実行するために必要な認知の労力が軽減され、感覚的な満足度も上がります。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_real_objects.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="make-it-mine">自分らしさを加える</h4>
+<p>ユーザーは自分でカスタマイズすることを好みます。これにより、くつろいだ気分や自分の思いのままできる自由な気分を味わうことができます。デフォルトで実用的で美しいものを取りそろえ、それに加えてメイン タスクの妨げにならない、楽しいカスタマイズも任意で加えられます。
+
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_make_it_mine.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="get-to-know-me">ユーザーについて知る</h4>
+<p>徐々にユーザーの好みを学習していきます。同じ選択を繰り返す手間をかけず、前に選択したものをすぐに選べるようになります。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_get_to_know_me.png">
+
+ </div>
+</div>
+
+<h2 id="simplify-my-life">よりシンプルに</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="keep-it-brief">常に簡潔に</h4>
+<p>シンプルな言葉を並べた短いフレーズを用います。長い文章は好まれません。</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_keep_it_brief.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="pictures-faster-than-words">画像は言葉よりもわかりやすい</h4>
+<p>画像を使ってアイデアを説明してみましょう。ユーザーの興味を引くことができ、言葉よりも効率的です。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_pictures.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="decide-for-me">選択は最小限に、最終決定はユーザーに</h4>
+<p>最初からユーザーにすべて尋ねるのではなく、もっとも適切と思われる項目を提示します。選択肢や決定事項が多すぎると面倒に感じます。
+推測が間違っていた場合に備え、「やり直し」も可能にします。</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_decide_for_me.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="only-show-when-i-need-it">必要なものを必要なときにだけ表示する</h4>
+<p>一度に表示される内容が多すぎると疲れてしまいます。タスクや情報はいくつかに小さくまとめてわかりやすくします。
+その時点で必要のないオプションは非表示にして、必要なときだけ表示します。</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_information_when_need_it.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="always-know-where-i-am">全体像から現在の位置を示す</h4>
+<p>ユーザーがはっきりと自分の現在の場所を把握できるようにします。アプリのどの場所にいるかを明示し、遷移して画面の関係を認識できるようにします。
+実行しているタスクに対して応答し続けます。</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_navigation.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="never-lose-my-stuff">作成したものは失くさない</h4>
+<p>ユーザーが時間をかけて作ったものは保存して、どこからでもアクセスできるようにします。設定、独自のカスタマイズ、電話、タブレット、コンピュータで作成したものを記録します。
+アップグレードも簡単になります。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_never_lose_stuff.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="looks-same-should-act-same">見た目が同じ場合は機能も同じにする</h4>
+<p>視覚的な違いを際立たせ、ユーザーが機能の違いをはっきり区別できるようにします。同じような外観、同じ入力で機能が異なるようなモードは避けます。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_looks_same.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="interrupt-only-if-important">割り込みは重要なときにだけ行う</h4>
+<p>優秀な個人秘書のように、重要ではない些細なことでユーザーをわずらわせることのないよう配慮します。集中したいユーザーにとって、重要で一刻を争うようなものでない限り、割り込まれると面倒で不快に感じる可能性があります。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_important_interruption.png">
+
+ </div>
+</div>
+
+<h2 id="make-me-amazing">操作を楽しく</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="give-me-tricks">あらゆる場所に工夫を仕込む</h4>
+<p>自分で理解すると嬉しく感じられます。Android アプリで広く使われている視覚や操作のパターンを生かし、アプリの操作をわかりやすいものにします。
+たとえばスワイプ操作は便利なナビゲーションのショートカットとして使えます。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_tricks.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="its-not-my-fault">解決は簡単に</h4>
+<p>ユーザーに修正を促す場合はその方法に注意します。アプリではスマートに問題を解決できるようにします。うまくいかなかったときは解決方法を明確に示し、技術的な詳細を表示する必要はありません。自動的に修正できる問題はユーザーに通知する必要すらありません。
+
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_error.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="sprinkle-encouragement">操作を促すしかけを散りばめる</h4>
+<p>複雑なタスクは分割し、それぞれ簡単に達成できるようにします。1 つ 1 つにフィードバックすることで、ユーザーの満足度は高まります。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_sprinkle_encouragement.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="do-heavy-lifting-for-me">作業の手間はかけない</h4>
+<p>できると思っていなかったことをできるようにすることで、知識がなくても専門家のような気分を味わってもらえます。たとえば複数の写真効果を組み合わせたショートカットを使うことで、わずかな手順でプロのような写真に仕上げられます。
+
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_heavy_lifting.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="make-important-things-fast">重要なことはすみやかに</h4>
+<p>すべてのアクションが同じ優先度とは限りません。アプリのアクションには優先度を設定し、重要なものはたとえばカメラのシャッター ボタンや音楽プレイヤーの一時停止ボタンのように、簡単に見つけられすぐに使えるようにします。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_make_important_fast.png">
+
+ </div>
+</div>
diff --git a/docs/html-intl/intl/ja/design/material/index.jd b/docs/html-intl/intl/ja/design/material/index.jd
new file mode 100644
index 0000000..3acd423
--- /dev/null
+++ b/docs/html-intl/intl/ja/design/material/index.jd
@@ -0,0 +1,186 @@
+page.title=マテリアル デザイン
+page.tags=Material, design
+page.type=design
+page.image=design/material/images/MaterialLight.png
+
+@jd:body
+
+<!-- developer docs box -->
+<a class="notice-developers right" href="{@docRoot}training/material/index.html">
+ <div>
+ <h3>デベロッパー文書</h3>
+ <p>マテリアル デザインを使ったアプリの作成</p>
+ </div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw">
+<div>
+ <h3>ビデオ</h3>
+ <p>マテリアル デザインについて</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw">
+<div>
+ <h3>ビデオ</h3>
+ <p>紙とインク:重要なマテリアル</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc">
+<div>
+ <h3>ビデオ</h3>
+ <p>Google I/O アプリのマテリアル デザイン</p>
+</div>
+</a>
+
+
+
+<p itemprop="description">マテリアル デザインは、視覚や動作と、複数のプラットフォームや端末間でのインタラクション デザインに関する包括的な指針です。
+Android はマテリアル デザイン アプリに対応するようになりました。
+Android アプリでマテリアル デザインを使うには、<a href="http://www.google.com/design/spec">マテリアル デザインの仕様</a>で説明されているガイドラインに従い、Android 5.0(API レベル 21)以降の新しいコンポーネントや機能を使用します。
+
+</p>
+
+<p>Android にはマテリアル デザインの作成に使うことができる次の要素が用意されています。</p>
+
+<ul>
+ <li>新しいテーマ</li>
+ <li>複雑なビュー用の新しいウィジェット</li>
+ <li>カスタムのシャドウとアニメーション用の新しい API</li>
+</ul>
+
+<p>Android でのマテリアル デザインの実装については、<a href="{@docRoot}training/material/index.html">マテリアル デザインを使ったアプリの作成</a>をご覧ください。
+</p>
+
+
+<h3>マテリアル テーマ</h3>
+
+<p>マテリアル テーマはアプリの新しいスタイルである、システム ウィジェットを提供します。システム ウィジェットを使ってカラーパレット、タッチ フィードバックやアクティビティ遷移のためのデフォルトのアニメーションを指定できます。
+</p>
+
+<!-- two columns -->
+<div style="width:700px;margin-top:25px;margin-bottom:20px">
+<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>
+ </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>
+ </div>
+</div>
+<br style="clear:left"/>
+</div>
+
+<p>詳細については、<a href="{@docRoot}training/material/theme.html">マテリアル テーマの使用</a>をご覧ください。
+</p>
+
+
+<h3>リストとカード</h3>
+
+<p>Android はマテリアル デザインのスタイルとアニメーションを含むカードとリストを表示する新しい 2 つのウィジェットを提供しています。
+</p>
+
+<!-- two columns -->
+<div style="width:700px;margin-top:25px;margin-bottom:20px">
+<div style="float:left;width:250px;margin-left:40px;margin-right:60px;">
+ <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" />
+ <p><code>RecyclerView</code> ウィジェットは <code>ListView</code> のさらに柔軟なバージョンで、さまざまなレイアウト タイプをサポートしてパフォーマンスを向上します。
+</p>
+</div>
+<div style="float:left;width:250px;margin-right:0px;">
+ <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" />
+ <p>新しい <code>CardView</code> ウィジェットでは、外観や使用感が一貫しているカード内に重要な情報を表示できます。
+</p>
+</div>
+<br style="clear:left"/>
+</div>
+
+<p>詳細については、<a href="{@docRoot}training/material/lists-cards.html">リストとカードの作成</a>をご覧ください。
+</p>
+
+
+<h3>シャドウの表示</h3>
+
+<p>X と Y プロパティに加え、Android のビューに Z プロパティが追加されました。
+この新しいプロパティはビューのエレベーションを表し、次を指定します。</p>
+
+<ul>
+<li>シャドウのサイズ: Z 値が高いビューほどキャストするシャドウのサイズが大きくなります。</li>
+<li>表示される順序: Z 値が高いビューほど他のビューより上位に表示されます。</li>
+</ul>
+
+<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/videos/ContactsAnim.webm"/>
+ <source src="{@docRoot}design/videos/ContactsAnim.ogv"/>
+ </video>
+ </div>
+ <div style="font-size:10pt;margin-left:20px;margin-bottom:30px">
+ <em>端末の画像をクリックすると動画を再生できます</em>
+ </div>
+</div>
+
+<p>詳細については、<a href="{@docRoot}training/material/shadows-clipping.html">シャドウとクリッピング ビューの定義</a>をご覧ください。
+</p>
+
+
+<h3>アニメーション</h3>
+
+<p>新しいアニメーション API を使って UI コントロールのタッチ フィードバック、ビューの状態遷移、アクティビティ遷移のカスタム アニメーションを作成できます。
+</p>
+
+<p>これらの API で次の操作を実行できます。</p>
+
+<ul>
+<li style="margin-bottom:15px">
+<strong>タッチ フィードバック</strong> アニメーションを使ってビューのタップイベントに応答します。
+</li>
+<li style="margin-bottom:15px">
+<strong>円形状の出現</strong>アニメーションを使ってビューを表示 / 非表示にします。
+</li>
+<li style="margin-bottom:15px">
+カスタムの<strong>アクティビティ遷移</strong>アニメーションを使ってアクティビティを切り替えます。
+</li>
+<li style="margin-bottom:15px">
+<strong>曲線モーション</strong>を使ってより自然なアニメーションを作成します。
+</li>
+<li style="margin-bottom:15px">
+<strong>ビューの状態遷移</strong>アニメーションを使って 1 つ以上のビュー プロパティの遷移を表現します。
+</li>
+<li style="margin-bottom:15px">
+ビューの状態遷移間のアニメーションを<strong>状態リスト ドローアブル</strong>で表示します。
+</li>
+</ul>
+
+<p>タッチ フィードバック アニメーションはボタンなどの複数の標準ビューに組み込まれます。新しい API を使ってこれらのアニメーションをカスタマイズし、それらをカスタム ビューに追加できます。
+</p>
+
+<p>詳細については、<a href="{@docRoot}training/material/animations.html">カスタム アニメーションの定義</a>をご覧ください。
+</p>
+
+
+<h3>ドローアブル</h3>
+
+<p>次の新しいドローアブル機能を使ってマテリアル デザイン アプリを実装できます。</p>
+
+<ul>
+<li><strong>ベクター型ドローアブル</strong>は鮮明度を失わずに拡張でき、単色のアプリ内アイコンに最適です。
+</li>
+<li><strong>ドローアブルによる着色</strong>を使ってビットマップをアルファマスクとして定義し、実行時にそれらのビットマップに色付けすることができます。
+</li>
+<li><strong>色の抽出</strong>を使ってビットマップ画像から代表色を自動的に抽出できます。
+</li>
+</ul>
+
+<p>詳細については、<a href="{@docRoot}training/material/drawables.html">ドローアブルの使用</a>をご覧ください。
+</p>
diff --git a/docs/html-intl/intl/ja/design/patterns/confirming-acknowledging.jd b/docs/html-intl/intl/ja/design/patterns/confirming-acknowledging.jd
new file mode 100644
index 0000000..35ba821
--- /dev/null
+++ b/docs/html-intl/intl/ja/design/patterns/confirming-acknowledging.jd
@@ -0,0 +1,70 @@
+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">
+ <img src="{@docRoot}design/media/confirm_ack_confirming.png">
+ <p><strong>確認</strong>とは、呼び出したアクションを続けるかどうかをユーザーに確認してもらうことです。場合によって、確認は考慮する必要があるアクションに関連する警告や重要情報とともに表示されることがあります。</p>
+ </div>
+ <div class="layout-content-col span-6">
+ <img src="{@docRoot}design/media/confirm_ack_acknowledge.png">
+ <p><strong>通知</strong>とは、呼び出したアクションが完了したことをユーザーにお知らせするテキストを表示することです。これによって、システムが実行している暗黙的な処理の不明瞭さをなくすことができます。場合によって、通知はアクションを元に戻すオプションとともに表示されることがあります。</p>
+ </div>
+</div>
+
+<p>このような方法でユーザーに情報を伝えると、実行された処理やこれから実行される処理についての不明瞭さを軽減できます。確認や通知によって、後悔するような間違いをするのを防ぐこともできます。</p>
+
+<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">
+ <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">
+ <h4>例: Android Beam</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_beam.png">
+ <p>確認は、必ずしも 2 つのボタンの付いたアラートで示す必要はありません。Android Beam を開始した後に、ユーザーには共有するコンテンツ(この例では写真)にタップするように求めるメッセージが表示されます。共有を続行しない場合は、電話を離すだけです。</p>
+ </div>
+</div>
+
+<h2>通知</h2>
+<div class="layout-content-row">
+ <div class="layout-content-col span-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">
+ <h4>例: Gmail スレッドの削除</h4>
+ <img src="{@docRoot}design/media/confirm_ack_draft_deleted.png">
+ <p>ユーザーが Gmail のリストからスレッドを削除した後に、元に戻すオプションとともに通知が表示されます。ユーザーがリストのスクロールなど関連しないアクションを実行するまで通知は表示されたままになります。</p>
+ </div>
+</div>
+
+<h2>確認または通知を行わない場合</h2>
+<div class="layout-content-row">
+ <div class="layout-content-col span-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">
+ <h4>例: ホームスクリーンからアプリを削除</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_removeapp.png">
+ <p><strong>確認は不要</strong>。これは意図的なアクションです。ユーザーはアイテムを比較的大きな分離されたターゲットにドラッグ アンド ドロップする必要があります。そのため、不測の問題が発生することはほとんどありません。ユーザーがこの決定を元に戻したい場合は、ほんの数秒で元に戻すことができます。</p>
+ <p><strong>通知は不要</strong>。ユーザーは自分でアプリをドラッグして削除するため、アプリがホームスクリーンから消えることがわかっています。</p>
+
+ </div>
+</div>
diff --git a/docs/html-intl/intl/ja/design/patterns/navigation.jd b/docs/html-intl/intl/ja/design/patterns/navigation.jd
new file mode 100644
index 0000000..dbb6b04
--- /dev/null
+++ b/docs/html-intl/intl/ja/design/patterns/navigation.jd
@@ -0,0 +1,213 @@
+page.title=Back と Up を使用したナビゲーション
+page.tags="navigation","activity","task","up navigation","back navigation"
+page.image=/design/media/navigation_between_siblings_gmail.png
+@jd:body
+
+<a class="notice-developers" href="{@docRoot}training/implementing-navigation/index.html">
+ <div>
+ <h3>デベロッパー文書</h3>
+ <p>効果的なナビゲーションを実装する</p>
+ </div>
+</a>
+
+<p itemprop="description">一貫したナビゲーションは全体的なユーザーの操作性を向上するために欠かせない重要な要素です。一貫性がなく予測できない動作ほどユーザーにとって不快なものはありません。
+Android 3.0 では、全体的なナビゲーション動作が大きく変更されました。
+注意深く Back と Up のガイドラインに従うことで、アプリのナビゲーションをユーザーにとって予測可能で信頼できるものにすることができます。
+</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">Up と Back</h2>
+
+<p>Up ボタンは、画面間の階層関係に基づいてアプリ内を移動するために使います。
+たとえば、画面 A がアイテムのリストを表示し、アイテムを選択すると(そのアイテムの詳細を表示する)画面 B に移動する場合、画面 B には画面 A に戻るための Up ボタンを用意する必要があります。
+
+</p>
+<p>画面がアプリの最上位(つまり、アプリのホーム)であれば、Up ボタンを表示すべきではありません。
+</p>
+
+<p>システムの Back ボタンはユーザーが最近使用した画面を、さかのぼって順番に移動する場合に使用されます。
+通常このナビゲーションはアプリの階層ではなく、画面を表示した順番に基づいています。
+</p>
+
+<p>前に表示していた画面が現在の画面の親階層となる場合は、Back ボタンを押すとUp ボタンを押したときと同じ結果になります &mdash; これはよくある動作です。
+
+ただし、Up ボタンではユーザーが確実にアプリ内に留まるのに対して、Back ボタンを使えばホームスクリーンに、さらには別のアプリに戻ることさえできます。
+</p>
+
+<img src="{@docRoot}design/media/navigation_up_vs_back_gmail.png">
+
+<p>Back ボタンは、画面間を直接ナビゲーションするだけでなく、次のような動作もサポートします。
+</p>
+<ul>
+<li>フローティング ウィンドウ(ダイアログ、ポップアップ)を閉じる</li>
+<li>コンテキスト アクションバーを閉じて、選択したアイテムのハイライト表示を解除する</li>
+<li>オンスクリーン キーボード(IME)を非表示にする</li>
+</ul>
+<h2 id="within-app">アプリ内でのナビゲーション</h2>
+
+<h4>複数のエントリ ポイントのある画面のナビゲーション</h4>
+<p>画面にアプリ階層内の正確な位置がなく、アプリ内の他のどの画面からでもアクセスできる設定画面などのように複数のエントリ ポイントからアクセスできる場合があります。この場合、Up ボタンは参照元の画面に戻ることを選択する必要があります。これは Back も同様です。
+&mdash;
+
+</p>
+<h4>画面内でビューを変更する</h4>
+<p>画面のビュー オプションを変更しても Up と Back の動作は変わりません。画面はアプリの階層内の同じ位置に留まり、新しいナビゲーション履歴は作成されません。
+</p>
+<p>このようなビューの変更には次のようなものがあります。</p>
+<ul>
+<li>タブや左右のスワイプを使ってビューを切り替える</li>
+<li>ドロップダウン(折りたたみタブ)を使ってビューを切り替える</li>
+<li>リストにフィルタをかける</li>
+<li>リストをソートする</li>
+<li>表示の方法を変える(ズームなど)</li>
+</ul>
+<h4>兄弟画面間のナビゲーション</h4>
+<p>アプリでアイテムのリストから 1 つのアイテム詳細画面に移動するとき、そのアイテムからリスト内の前後にある別のアイテムへのナビゲーションをサポートするのが望ましいことがよくあります。
+
+たとえば、Gmail では、スワイプすることで、ある会話から同じ受信トレイの新しいまたは古い会話へ左右に簡単に移動できます。
+画面内でビューを変更する場合と同じように、このようなナビゲーションによって Up または Back の動作は変わりません。
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_gmail.png">
+
+<p>しかし、参照リストで結び付けられていない関連詳細ビュー間をブラウジングする場合 &mdash; たとえば Play ストアで同じデベロッパーのアプリや同じアーティストのアルバム間をブラウジング場合、その動作はこれとは明らかに異なります。
+
+この場合、各リンクをたどると履歴が作成され、Back ボタンで以前に表示した各画面に戻ることになります。
+Up では常にこれらの関連画面をバイパスして、直前に表示したコンテナ画面に移動します。
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_market1.png">
+
+<p>Up の動作を詳細ビューの知識に基づいてより使いやすくすることができます。
+前述の Play ストアの例で、ユーザーが直前に表示した書籍から映画版の詳細に移動したとします。
+その場合、Up でユーザーが前に表示していないコンテナ(映画)に戻ることができます。
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_market2.png">
+
+<h2 id="into-your-app">ホームスクリーンのウィジェットと通知によるアプリへのナビゲーション</h2>
+
+<p>ホームスクリーンのウィジェットや通知を使ってユーザーがアプリ階層内の深い階層にある画面に直接移動できるようにします。
+たとえば、Gmail の受信ボックスのウィジェットと新しいメッセージ通知はどちらも受信トレイ画面をバイパスし、会話ビューを直接表示できます。
+</p>
+
+<p>この両方の機能で、Up ボタンを次のように処理します。</p>
+
+<ul>
+<li><em>通常アプリ内の特定の画面から移動先画面に移動する場合</em>、Up でその画面に移動します。
+</li>
+<li><em>それ以外の場合は</em>、Up でアプリの最上位(「ホーム」)画面に移動します。</li>
+</ul>
+
+<p>Back ボタンの場合は、アプリの最上位画面への完全な上向きナビゲーション パスをタスクのバックスタックに挿入してナビゲーションをより予測可能なものにする必要があります。
+この設定によって、アプリにどのように入ったか忘れたユーザーは、終了前のアプリの最上位画面に移動できます。
+
+</p>
+
+<p>たとえば Gmail のホームスクリーンのウィジェットには、その作成画面に直接移動するボタンがあります。
+作成画面の Up または Back で受信トレイが表示され、そこから Back ボタンでホームに移動します。
+</p>
+
+<img src="{@docRoot}design/media/navigation_from_outside_back.png">
+
+<h4>間接通知</h4>
+
+<p>アプリで複数のイベントに関する情報を同時に表示する必要がある場合、1 つの通知を使ってユーザーをインタースティシャル画面に導くことができます。
+この画面にはこれらのイベントがまとめてあり、アプリのさらに深い階層に移動するためのパスが示されます。このスタイルの通知を<em>間接通知</em>と呼びます。
+
+</p>
+
+<p>標準(直接)通知とは異なり、間接通知のインタースティシャル画面から Back を押すとユーザーは通知がトリガーされた地点に戻ります &mdash; バックスタックには追加の画面は挿入されません。
+
+ユーザーがインタースティシャル画面からアプリに移動すると、Up および Back は前述した標準通知の場合と同様に動作します。つまりインタースティシャル画面に戻るのではなくアプリ内でナビゲーションします。
+
+</p>
+
+<p>たとえば Gmail のユーザーがカレンダーから間接通知を受け取ったとします。この通知をタップするとインタースティシャル画面が開き、複数の異なるイベントに関するリマインダーが表示されます。
+
+インタースティシャル画面で Back をタップすると Gmail に戻ります。特定のイベントをタップすると、インタースティシャル画面から完全なカレンダー アプリに移動し、そのイベントの詳細が表示されます。
+
+イベントの詳細から、Up および Back を使うとカレンダーの最上位ビューが表示されます。</p>
+
+<img src="{@docRoot}design/media/navigation_indirect_notification.png">
+
+<h4>ポップアップ通知</h4>
+
+<p><em>ポップアップ通知</em>は通知ドロワーをバイパスしてユーザーの前に直接表示されます。
+ポップアップ通知はめったに使われません。<strong>タイムリーな応答が要求され、ユーザーのコンテキストの中断が必要な場合に使われます</strong>。
+たとえばトークでは、このスタイルを使って友人からのビデオチャットへの参加に関する招待状についてユーザーに通知します。というのも、この招待状は数秒後に自動的に期限切れになるからです。
+
+</p>
+
+<p>ナビゲーション動作の点から、ポップアップ通知は間接通知のインタースティシャル画面の動作に厳密に従います。
+Back でポップアップ通知は閉じます。ユーザーがポップアップから通知元のアプリに移動すると、Up と Back は標準通知のルールに従い、アプリ内でナビゲーションします。
+
+</p>
+
+<img src="{@docRoot}design/media/navigation_popup_notification.png">
+
+<h2 id="between-apps">アプリ間のナビゲーション</h2>
+
+<p>Android システムの基本的な利点の 1 つにアプリ同士がそれぞれをアクティブにできる機能があります。これによりユーザーは特定のアプリから別のアプリへ直接移動できます。
+たとえば写真を撮影する必要があるアプリでは、カメラアプリをアクティブにすることができます。カメラアプリは写真を参照元のアプリに戻します。これはデベロッパーにとっては他のアプリのコードを簡単に利用できるという点で、またユーザーにとっては通常実行するアクションに対して一貫した操作を実行できるという点で大きなメリットです。
+
+
+
+</p>
+
+<p>アプリ間のナビゲーションを理解するには、次に説明する Android フレームワークの動作を理解することが重要です。
+</p>
+
+<h4>アクティビティ、タスク、インテント</h4>
+
+<p>Android における<strong>アクティビティ</strong>とは情報の画面と、ユーザーが実行できるすべての関連アクションを定義するアプリケーション コンポーネントです。
+アプリはアクティビティのコレクションで、作成したアクティビティと他のアプリから再利用するアクティビティの両方で構成されています。
+</p>
+
+<p><strong>タスク</strong>とは目標を実現するためにユーザーが従う一連のアクティビティです。1 つのタスクで 1 つのアプリだけのアクティビティを利用することも、複数のアプリのアクティビティを利用することもできます。
+
+</p>
+
+<p><strong>インテント</strong>とは、あるアプリがアクションの実行に関して別のアプリのサポートが必要であることを示すメカニズムです。
+アプリのアクティビティでそれらのアプリが対応できるインテントを示すことができます。
+「共有」などの一般的なインテントの場合、ユーザーはその要求を実現できる多くのアプリをインストールしている場合があります。
+</p>
+
+<h4>例: 共有をサポートするアプリ間のナビゲーション</h4>
+
+<p>アクティビティ、タスク、インテントの連携を理解するには、1 つのアプリが別のアプリを使ってユーザーによるコンテンツの共有を可能にする仕組みを知る必要があります。たとえばホームから Play ストアのアプリを起動すると、新しいタスク A が開始されるとします(以下の図を参照)。
+
+Play ストア内をナビゲートし、プロンプトで表示された書籍をタップしてその詳細を表示した後もユーザーは同じタスク内に留まり、アクティビティを追加するとタスクは拡張されます。
+「共有」アクションをトリガーすると、共有インテントを処理するよう登録されている(さまざまなアプリの)各アクティビティを示すダイアログがユーザー表示されます。
+
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_inward.png">
+
+<p>ユーザーが Gmail 経由で共有することを選択すると、Gmail の作成アクティビティがタスク A の続きとして追加されます &mdash; 新しいタスクは作成されません。
+Gmail にバックグラウンドで実行中の独自のタスクがある場合、そのタスクは影響を受けません。
+</p>
+
+<p>作成アクティビティからメッセージを送信するか、Back ボタンをタップするとユーザーは書籍の詳細アクティビティに戻ります。
+Back を連続してタップすると Play ストアに戻り、最終的にはホームが表示されます。
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_back.png">
+
+<p>ただし、作成アクティビティから Up をタップすると、ユーザーは Gmail 内に留まる意思を示すことになります。
+Gmail の会話リストのアクティビティが表示され、新しいタスク B が作成されます。新しいタスクは常にホームをルートとしているため、会話リストからBack をタップするとホームに戻ります。
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_up.png">
+
+<p>タスク A はバックグラウンドで維持され、ユーザー後から(たとえば [最近使ったアプリ] 画面経由で)このタスクに戻ることができます。
+Gmail にバックグラウンドで実行中の独自のタスクが既にある場合、そのタスクはタスク B に置き換えられます &mdash; 前のコンテキストはユーザーの新しい目標の導入より破棄されます。
+</p>
+
+<p>アプリがアプリ階層内の深い階層にあるアクティビティでインテントを処理するように登録されている場合は、Up ナビゲーションの指定方法について<a href="#into-your-app">ホームスクリーンのウィジェットと通知によるアプリへのナビゲーション</a>をご覧ください。
+
+</p>
diff --git a/docs/html-intl/intl/ja/design/patterns/notifications.jd b/docs/html-intl/intl/ja/design/patterns/notifications.jd
new file mode 100644
index 0000000..8c5b6ba
--- /dev/null
+++ b/docs/html-intl/intl/ja/design/patterns/notifications.jd
@@ -0,0 +1,872 @@
+page.title=通知
+page.tags="notifications","design","L"
+@jd:body
+
+ <a class="notice-developers" href="{@docRoot}training/notify-user/index.html">
+ <div>
+ <h3>デベロッパー文書</h3>
+ <p>ユーザーに通知する</p>
+ </div>
+</a>
+
+<a class="notice-designers" href="notifications_k.html">
+ <div>
+ <h3>Android 4.4 以前での通知</h3>
+ </div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=Uiq2kZ2JHVY">
+<div>
+ <h3>ビデオ</h3>
+ <p>DevBytes:Notifications in the Android L Developer Preview</p>
+</div>
+</a>
+
+<style>
+ .col-5, .col-6, .col-7 {
+ margin-left:0px;
+ }
+</style>
+
+<p>通知システムを使用すると、ユーザーは友人からの新しいチャット メッセージやカレンダー イベントなど、自分に関係のあるタイムリーなイベントについてアプリで常に通知を受けることができます。通知は、重要な出来事が起こるとすぐに知らせてくれるニュース チャンネルであり、ユーザーが意識していない間に出来事を時系列的に記録するログであると捉えることができます &mdash; さらに、すべての Android 端末で適宜同期されます。
+
+
+
+
+
+</p>
+
+<h4 id="New"><strong>Android 5.0 での新機能</strong></h4>
+
+<p>Android 5.0 において、通知は構造的に、視覚的に、機能的に重要なアップデートを受信します。
+</p>
+
+<ul>
+ <li>通知は、新しいマテリアル デザインのテーマにあわせて外観が変更されているところす。
+</li>
+ <li> 端末のロック画面で通知を利用できるようになりましたが、機密性の高いコンテンツはこれからも非表示にできます。
+
+</li>
+ <li>端末の使用中に受信した高優先度の通知において、ヘッドアップ通知と呼ばれる新しい形式が使用されるようになりました。
+</li>
+ <li>クラウド同期通知: 所有する Android 端末のどれかで通知を却下すると、他でも却下されます。
+
+</li>
+</ul>
+
+<p class="note"><strong>注</strong>: このバージョンの Android での通知設計は、従来のバージョンから大きく変わっています。
+
+これまでのバージョンの通知設計について詳しくは、<a href="./notifications_k.html">Android 4.4 以前での通知</a>をご覧ください。
+</p>
+
+<h2 id="Anatomy">通知の仕組み</h2>
+
+<p>このセクションでは、通知の基本パーツと各種端末における通知の表示について詳しく説明します。
+</p>
+
+<h3 id="BaseLayout">基本レイアウト</h3>
+
+<p>あらゆる通知の最低限の基本レイアウトは次のようになっています。</p>
+
+<ul>
+ <li> 通知の<strong>アイコン</strong>。このアイコンは通知元のアプリを示します。複数タイプの通知を生成するアプリでは、通知のタイプを示すことがあります。
+
+
+</li>
+ <li> 通知の<strong>タイトル</strong>と追加<strong>テキストメッセージ</strong>。
+</li>
+ <li> <strong>タイムスタンプ</strong>。</li>
+</ul>
+
+<p>従来のプラットフォーム バージョンの {@link android.app.Notification.Builder Notification.Builder} で作成された通知は、Android 5.0 でも同じように表示され、機能します。スタイルにいくらかの違いがありますが、システムが対処します。
+
+
+従来のバージョンの Android での通知について詳しくは、<a href="./notifications_k.html">Android 4.4 以前での通知</a>をご覧ください。
+
+</p></p>
+
+
+ <img style="margin:20px 0 0 0" src="{@docRoot}images/android-5.0/notifications/basic_combo.png" alt="" width="700px" />
+
+
+<div style="clear:both;margin-top:20px">
+ <p class="img-caption">
+ ユーザー フォトと通知アイコンを使用した、携帯端末での通知(左)と Wear での同じ通知(右)
+
+ </p>
+ </div>
+
+<h3 id="ExpandedLayouts">展開レイアウト</h3>
+
+
+<p>通知にどこまでの詳細を表示するかを選択できます。
+メッセージの最初の数行を表示したり、大きな画像プレビューを表示したりできます。
+追加情報はユーザーにより多くのコンテキストを提供し、&mdash;場合によっては&mdash;メッセージ全体が表示されることもあります。
+
+
+ユーザーは、ピンチ ズームまたは 1 本指のスワイプで、コンパクトなレイアウトと展開されたレイアウトを切り替えることができます。
+
+
+ 1 つのイベントに関する通知に対し、Android では 3 種類の展開レイアウト(テキスト、受信トレイ、画像)をアプリケーションで使用できるようにしています。
+
+次の図に、1 つのイベントに関する通知が携帯端末(左)とウェアラブル(右)でどのように見えるかを示します。
+
+</p>
+
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/expandedtext_combo.png"
+ alt="" width="700px" height;="284px" />
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/stack_combo.png"
+ alt="" width="700px" height;="284px" />
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/ExpandedImage.png"
+ alt="" width="311px" height;="450px" />
+
+<h3 id="actions" style="clear:both; margin-top:40px">アクション</h3>
+
+<p>Android では、通知の最下部に表示されるオプションのアクションをサポートしています。ここに示されるアクションを使用することで、ユーザーは特定の通知に対するほとんどの一般的なタスクを通知シェードで処理でき、通知元のアプリケーションを開く必要はありません。これによりやり取りがスピードアップし、スワイプで却下もできることから、ユーザーは自分に関係のある通知に集中しやすくなります。
+
+
+
+
+
+</p>
+
+
+ <img src="{@docRoot}images/android-5.0/notifications/action_combo.png" alt="" width="700px" />
+
+
+
+<p style="clear:both">通知に含めるアクションの数はほどほどに抑えることをお勧めします。
+含めるアクションを増やすほど、わかりにくくなるからです。
+もっとも差し迫った意味のある重要なアクションだけにして、アクションの数を最小限に抑えてください。
+
+
+</p>
+
+<p>通知に対するアクションとして好ましい候補は次のとおりです。</p>
+
+<ul>
+ <li> 表示するコンテンツ タイプに欠かせず、よく使われ、典型的である
+
+ <li> ユーザーがタスクを手早く完了できる
+</ul>
+
+<p>次のようなアクションは避けてください。</p>
+
+<ul>
+ <li> あいまいである
+ <li> 通知のデフォルト アクションと同じである(「読む」や「開く」など)
+
+</ul>
+
+
+
+<p>アクションは 3 つまで指定でき、それぞれにアクションのアイコンと名前が付きます。
+
+ シンプルな基本レイアウトにアクションを追加すると、展開レイアウトがない場合でも、通知は展開可能になります。
+
+アクションは展開可能な通知にのみ表示され、それ以外では非表示になることから、ユーザーが通知から起動できるどのアクションについても、関連アプリケーションからも利用できるようにしてください。
+
+
+
+
+</p>
+
+<h2 style="clear:left">ヘッドアップ通知</h2>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/hun-example.png" alt="" width="311px" />
+ <p class="img-caption">
+ イマーシブ アプリの最上部に表示されたヘッドアップ通知の例(電話の着信、高優先度)
+
+
+ </p>
+</div>
+
+<p>優先度の高い通知が作成されると(右図)、その展開レイアウトが可能なアクションとともに短時間表示されます。
+
+</p>
+<p> この時間が過ぎると、通知は通知シェードに戻ります。
+通知の<a href="#correctly_set_and_manage_notification_priority">優先度</a>を示すフラグが高、最大、全画面の場合は、ヘッドアップ通知になります。
+</p>
+
+<p><b>ヘッドアップ通知にふさわしい例</b></p>
+
+<ul>
+ <li> 端末使用中の電話の着信</li>
+ <li> 端末使用中のアラーム</li>
+ <li> 新しい SMS メッセージ</li>
+ <li> 低バッテリ残量</li>
+</ul>
+
+<h2 style="clear:both" id="guidelines">ガイドライン</h2>
+
+
+<h3 id="MakeItPersonal">パーソナルにする</h3>
+
+<p>他人から送信されたアイテム(メッセージ、ステータス アップデートなど)の通知には、{@link android.app.Notification.Builder#setLargeIcon setLargeIcon()} を使用して相手の画像を含めます。
+
+また、通知のメタデータに相手に関する情報を添付します({@link android.app.Notification#EXTRA_PEOPLE} を参照)。
+</p>
+
+<p>通知のメインアイコンは表示され続けるため、ユーザーはそれをステータスバーに表示されるアイコンと関連付けることができます。
+
+</p>
+
+
+<img src="{@docRoot}images/android-5.0/notifications/Triggered.png" alt="" width="311px" />
+<p style="margin-top:10px" class="img-caption">
+ 通知をトリガーした人と送信内容が表示された通知。
+</p>
+
+
+<h3 id="navigate_to_the_right_place">適切な画面へのナビゲーション</h3>
+
+<p>ユーザーが通知の本体(アクション ボタン以外)をタップしたら、アプリが開き、通知に表示されているデータの表示や操作ができる画面へ移動するようにします。
+
+
+ほとんどの場合、移動先はメッセージのような 1 つのデータアイテムの詳細表示になりますが、通知がスタックされている場合は概要ビューにすることも考えられます。
+
+アプリがユーザーをアプリの最上位レベルより下のどこかに移動する場合は、アプリのバックスタックにナビゲーションを挿入して、ユーザーがシステムの Back ボタンを押すと最上位レベルに戻れるようにします。
+
+詳しくは、<a href="{@docRoot}design/patterns/navigation.html#into-your-app">ナビゲーション</a>デザイン パターンの<em>ホーム画面ウィジェットと通知を経由するアプリへのナビゲーション</em>をご覧ください。
+
+</p>
+
+<h3 id="correctly_set_and_manage_notification_priority">通知優先度の適切な設定と管理
+
+</h3>
+
+<p>Android では、通知用の優先度フラグをサポートしています。このフラグを使用すると、通知の表示位置に他の通知との相対関係として影響を及ぼして、ユーザーが常に最重要の通知を真っ先に目にするようにできます。
+
+
+通知を投稿する際には、優先度を次の中から選べます。
+
+</p>
+<table>
+ <tr>
+ <td class="tab0">
+<p><strong>優先度</strong></p>
+</td>
+ <td class="tab0">
+<p><strong>用途</strong></p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>MAX</code></p>
+</td>
+ <td class="tab1">
+<p>重大で切迫した通知に対して使用します。緊急を要する状況、または特定のタスクを続ける前に解決する必要がある状況であることをユーザーに通告します。
+
+
+</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>HIGH</code></p>
+</td>
+ <td class="tab1">
+<p>主に重要な情報に対して使用します。ユーザーが特に関心を持ちそうなメッセージ イベントやチャット イベントなどが該当します。通知の優先度を高く設定すると、ヘッドアップ通知を表示できます。
+
+</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>DEFAULT</code></p>
+</td>
+ <td class="tab1">
+<p>ここで説明している他の優先度のどれにも該当しないすべての通知に対して使用します。</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>LOW</code></p>
+</td>
+ <td class="tab1">
+<p>ユーザーに知らせたいがそれほど緊急ではない通知に対して使用します。
+低優先度の通知は一般にリストの末尾に表示され、公の、または間接的なソーシャル アップデートなどに適しています。
+
+ユーザーがこうした通知の設定をしていても、急を要するコミュニケーションや直接的なコミュニケーションより優先されないようにする必要があります。
+
+
+</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>MIN</code></p>
+</td>
+ <td class="tab1">
+<p>天気予報や周辺位置情報のようなコンテキスト的またはバックグラウンド的な情報に対して使用します。最小優先度の通知はステータスバーに表示されません。
+
+ユーザーは通知シェードを展開したときにその存在に気づきます。
+</p>
+</td>
+ </tr>
+</table>
+
+
+<h4 id="how_to_choose_an_appropriate_priority"><strong>適切な優先度の選び方</strong>
+
+</h4>
+
+<p><code>DEFAULT</code>、<code>HIGH</code>、<code>MAX</code> は中断を伴う優先度レベルで、ユーザーによるアクティビティに割り込むリスクがあります。
+
+アプリのユーザーに不快に思われないようにするため、割り込みを伴う優先度レベルの通知は次のような場合に限定してください。
+</p>
+
+<ul>
+ <li> 他人が絡む</li>
+ <li> 急を要する</li>
+ <li> 実世界におけるユーザーの行動が直ちに変わりうる</li>
+</ul>
+
+<p><code>LOW</code> や <code>MIN</code> に設定されている通知も、ユーザーにとって価値がある可能性はあります。
+ほとんどとは言わないまでも、多くの通知は、ユーザーの注意を直ちに引く、またはユーザーの手首に振動を与える必要はありませんが、ユーザーがその通知を見ることにしたときに価値があると気づくような情報が含まれている必要があります。
+
+
+優先度が <code>LOW</code> や <code>MIN</code> の通知の条件は以下のとおりです。
+</p>
+
+<ul>
+ <li> 他人が絡まない</li>
+ <li> 急を要さない</li>
+ <li> ユーザーが興味を持ちうる内容が含まれているが、手が空いたときに参照することにして問題ない
+</li>
+</ul>
+
+
+ <img src="{@docRoot}images/android-5.0/notifications/notifications_pattern_priority.png" alt="" width="700" />
+
+
+<h3 style="clear:both" id="set_a_notification_category">通知カテゴリの設定
+</h3>
+
+<p>通知が、あらかじめ定義されているカテゴリ(下を参照)のどれかに該当する場合は、それに沿って割り当てます。
+
+通知シェード(やその他の通知リスナー)などの各種システム UI は、評価やフィルタリングの判断にこの情報を使用することがあります。
+
+</p>
+<table>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_CALL">CATEGORY_CALL</a></code></p>
+</td>
+ <td>
+<p>電話(ビデオまたは音声)の着信またはそれに類する同期通信の要求
+</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_MESSAGE">CATEGORY_MESSAGE</a></code></p>
+</td>
+ <td>
+<p>直接メッセージ(SMS、インスタントメッセージなど)の受信</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_EMAIL">CATEGORY_EMAIL</a></code></p>
+</td>
+ <td>
+<p>非同期バルク メッセージ(メール)</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_EVENT">CATEGORY_EVENT</a></code></p>
+</td>
+ <td>
+<p>カレンダー イベント</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_PROMO">CATEGORY_PROMO</a></code></p>
+</td>
+ <td>
+<p>販促または広告</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_ALARM">CATEGORY_ALARM</a></code></p>
+</td>
+ <td>
+<p>アラームまたはタイマー</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_PROGRESS">CATEGORY_PROGRESS</a></code></p>
+</td>
+ <td>
+<p>長時間実行のバックグラウンド処理の進捗</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SOCIAL">CATEGORY_SOCIAL</a></code></p>
+</td>
+ <td>
+<p>ソーシャル ネットワークまたは共有アップデート</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_ERROR">CATEGORY_ERROR</a></code></p>
+</td>
+ <td>
+<p>バックグラウンド処理または認証ステータスにおけるエラー</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_TRANSPORT">CATEGORY_TRANSPORT</a></code></p>
+</td>
+ <td>
+<p>再生のためのメディア転送コントロール</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SYSTEM">CATEGORY_SYSTEM</a></code></p>
+</td>
+ <td>
+<p>システムまたは端末のステータス アップデート。システム用に予約済み。</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SERVICE">CATEGORY_SERVICE</a></code></p>
+</td>
+ <td>
+<p>バックグラウンド サービス実行中の表示。</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_RECOMMENDATION">CATEGORY_RECOMMENDATION</a></code></p>
+</td>
+ <td>
+<p>1 つの事項に対する具体的でタイムリーな推奨。たとえば、ニュースアプリがユーザーが次に読みたいのではないかと予想した記事を推奨するなど。
+
+</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_STATUS">CATEGORY_STATUS</a></code></p>
+</td>
+ <td>
+<p>端末やコンテキスト ステータスに関する進行中情報。</p>
+</td>
+ </tr>
+</table>
+
+<h3 id="summarize_your_notifications">通知の概要</h3>
+
+<p>アプリで特定の新しい通知を送信しようとしたときに同じタイプの通知が既に保留されていた場合は、それらを統合してそのアプリに対する 1 つの概要通知にします。新しいオブジェクトは作成しないでください。
+
+</p>
+
+<p>概要通知は概要説明を作成し、特定タイプの通知がいくつ保留になっているのかがユーザーにわかるようにします。
+
+</p>
+
+<div class="col-6">
+
+<p><strong>非推奨</strong></p>
+ <img src="{@docRoot}images/android-5.0/notifications/Summarise_Dont.png" alt="" width="311px" />
+</div>
+
+<div>
+<p><strong>推奨</strong></p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/Summarise_Do.png" alt="" width="311px" />
+</div>
+
+<p style="clear:left; padding-top:30px; padding-bottom:20px">概要を構成している個々の通知に関する詳細は、展開ダイジェスト レイアウトを使用して提示できます。
+
+このアプローチにより、ユーザーはどの通知が保留中か、そして関連アプリで詳しく読もうと思うほどそれらに興味があるかを把握しやすくなります。
+
+
+
+</p>
+<div class="col-6">
+ <img src="{@docRoot}images/android-5.0/notifications/Stack.png" style="margin-bottom:20px" alt="" width="311px" />
+ <p class="img-caption">
+ 通知の展開された概要と折りたたまれた概要(<code>InboxStyle</code> を使用)
+ </p>
+</div>
+
+<h3 style="clear:both" id="make_notifications_optional">通知をオプションにする
+</h3>
+
+<p>ユーザーは常に通知を制御できる必要があります。アプリケーションの設定に通知設定アイテムを追加して、ユーザーがアプリの通知を無効にしたり、警告音や振動を使用するかどうかなどのアラート設定を変更したりできるようにしてください。
+
+
+
+</p>
+
+<h3 id="use_distinct_icons">見分けやすいアイコンにする</h3>
+<p>現在保留になっているのがどのタイプの通知なのか、ユーザーが通知エリアを一目で見分けられることが必要です。
+
+</p>
+
+<div class="figure">
+ <img src="{@docRoot}images/android-5.0/notifications/ProductIcons.png" alt="" width="420" />
+</div>
+
+ <div><p><strong>推奨</strong></p>
+ <p>Android アプリが既に提供している通知アイコンを見ながら、独自アプリ用に見かけの十分異なるアイコンを作成する。
+
+</p>
+
+ <p><strong>推奨</strong></p>
+ <p>小さなアイコン用の適切な<a href="/design/style/iconography.html#notification">通知アイコン スタイル</a>と、アクション アイコン用の Material Light <a href="/design/style/iconography.html#action-bar">アクションバー アイコンスタイル</a>を使う。
+
+
+
+</p>
+<p ><strong>推奨</strong></p>
+<p >アイコンの見た目はシンプルに保ち、細かくしすぎて見にくくならないようにする。
+</p>
+
+ <div><p><strong>非推奨</strong></p>
+ <p>なんらかの追加アルファ(暗転やフェード)を小さなアイコンやアクション アイコンに配置する。エッジはアンチ エイリアス処理できますが、Android ではこれらのアイコンをマークとして使用するため(つまり、アルファ チャンネルのみ使用)、画像は概して完全不透明で描画されます。
+
+
+
+
+</p>
+
+</div>
+<p style="clear:both"><strong>非推奨</strong></p>
+
+<p>アプリを他と色で区別する。通知アイコンは、背景が透明な白に限定してください。
+</p>
+
+
+<h3 id="pulse_the_notification_led_appropriately">通知 LED を適切に点灯させる
+</h3>
+
+<p>多くの Android 端末には通知 LED が用意されており、スクリーンがオフのときでもユーザーに引き続きイベントを通知するために使用されます。
+
+優先度が <code>MAX</code>、<code>HIGH</code>、<code>DEFAULT</code> の通知を LED 点灯するようにし、優先度の低い通知(<code>LOW</code> と <code>MIN</code>)は点灯しないようにしてください。
+
+
+</p>
+
+<p>ユーザーによる通知の制御が LED にも及ぶようにしてください。DEFAULT_LIGHTS を使用すると、LED が白く点灯します。
+
+ユーザーが明示的にカスタマイズしない限り、通知では別の色を使用しないでください。
+
+</p>
+
+<h2 id="building_notifications_that_users_care_about">ユーザーが気にする通知の作成
+</h2>
+
+<p>ユーザーに愛されるアプリを開発するためには、通知を入念にデザインすることが重要です。通知はアプリの声を体現するものであり、アプリの個性の一部です。
+
+
+望まれない通知や重要ではない通知がユーザーの邪魔になったり、アプリへの注目を集める意図が逆にユーザーに不快に思われたりしかねませんので、通知は適切に使用してください。
+
+
+</p>
+
+<h3 id="when_to_display_a_notification">通知を表示すべきケース</h3>
+
+<p>ユーザーが楽しんで使えるアプリケーションを開発するには、ユーザーの注目や関心は保護すべきリソースであるという認識が重要です。
+
+Android の通知システムは、ユーザーの注意に対する通知のインパクトを最小限に抑える設計になっていますが、通知がユーザーのタスクフローに割り込むという事実を意識することがやはり重要です。通知を盛り込む予定の場合は、それが割り込みに値するほど重要かどうかを自問してください。
+
+
+
+
+
+
+確信が持てない場合は、ユーザーがアプリの通知設定を使用して通知をコントロールできるようにするか、通知のフラグを <code>LOW</code> か <code>MIN</code> に設定してユーザーがしている別のことを邪魔しないようにします。
+
+
+
+</p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/TimeSensitive.png" alt="" width="311px" />
+ <p style="margin-top:10px" class="img-caption">
+ 急を要する通知の例
+ </p>
+
+<p>概して、適切に振る舞うアプリは話しかけられたときだけ口を開きますが、求められていない通知でユーザーの作業に割り込むことにメリットがあるケースもいくつか存在します。
+</p>
+
+<p>通知は主に<strong>急を要するイベント</strong>で、特に<strong>他人が絡む</strong>同期イベントで使用します。
+たとえば、受信チャットはリアルタイムの同期コミュニケーションです。
+
+他人が応答を能動的に待っています。
+カレンダー イベントも、通知でユーザーの注目を引くタイミングに関する好例です。なぜなら、そうしたイベントは差し迫っており、往々にして他人が絡みます。
+
+
+</p>
+
+<h3 style="clear:both" id="when_not_to_display_a_notification">通知を表示すべきでないケース
+</h3>
+
+<div class="figure" style="margin-top:60px">
+ <img src="{@docRoot}images/android-5.0/notifications/AntiSample1.png" alt="" width="311px" />
+</div>
+
+<p>以上を除く多くの場合、通知の使用は適切ではありません。</p>
+
+<ul>
+ <li> 明示的にユーザー宛てではない情報や、それほど急を要さない情報は、ユーザーへの通知を避けます。
+
+たとえば、ソーシャル ネットワーク経由で流れてくる非同期の間接的なアップデートは、概してリアルタイムの割り込みにふさわしくありません。
+
+
+それらに本当に関心のあるユーザーが選択できるようにします。
+</li>
+ <li> 関連する新しい情報が現在画面に表示されている場合は、通知を作成しないようにします。
+その代わり、アプリケーションそのものの UI を使用して、ユーザーに情報をコンテキスト内で直接通知します。
+
+
+ たとえば、チャット アプリケーションは、ユーザーが他のユーザーとチャットしている最中にシステム通知を作成しないようにします。
+</li>
+ <li> 情報の保存や同期、アプリケーションのアップデートなど、低レベルの技術的な通知については、アプリやシステムがユーザーの介入なしに問題を解決できる場合は割り込まないようにします。
+
+</li>
+ <li> アプリケーションがユーザーの介入なしにエラーから復旧できる場合は、そのようなエラーの通知で割り込まないでください。
+
+</li>
+ <li> 通知にふさわしい内容がなく、アプリを宣伝するだけの通知は、作成しないようにします。通知は、有益でタイムリーな新しい情報を提供するものであり、アプリを起動するためだけには使用しないでください。
+
+
+
+</li>
+ <li> ブランドをユーザーの目の前に提示するだけの表面的な通知を作成しないようにします。
+
+ そうした通知はユーザーにフラストレーションを与え、アプリが使われなくなります。アップデートされた情報を少しだけ提供し、ユーザーをアプリにつなぎ止める最適な方法は、ホームスクリーンに配置できるウィジェットを開発することです。
+
+
+
+
+</li>
+</ul>
+
+<h2 style="clear:left" id="interacting_with_notifications">通知の操作
+</h2>
+
+<p>通知はステータスバーにアイコンとして示され、通知ドロワーを開いてアクセスできます。
+
+</p>
+
+<p>通知をタップすると関連アプリが開き、その通知に対応する詳細なコンテンツに移動します。通知上で左か右にスワイプされた通知は、ドロワーから削除されます。
+
+</p>
+
+<h3 id="ongoing_notifications">進行中通知</h3>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/MusicPlayback.png" alt="" width="311px" />
+ <p class="img-caption">
+ 音楽再生の進行中通知
+ </p>
+</div>
+<p>進行中通知は、バックグラウンドで進行中の処理に関する情報をユーザーに伝えます。たとえば、音楽プレイヤーは通知システムで現在再生中のトラックを示し、ユーザーが再生を停止するまで通知を継続します。
+
+
+
+進行中通知には、ファイルのダウンロードやビデオのエンコードなど、時間のかかるタスクに対するフィードバックをユーザーに示すこともできます。
+
+ユーザーは、進行中通知を通知ドロワーから手動では削除できません。
+</p>
+
+<h3 id="ongoing_notifications">メディア再生</h3>
+<p>Android 5.0 では、廃止された {@link android.media.RemoteControlClient} クラスの転送コントロールがロック画面に表示されません。
+ただし、通知が表示されるため、<em></em>ユーザーがロック状態から再生をコントロールするための主な手段は、現状では各アプリの再生通知です。
+
+この動作により、アプリは表示するボタンとその表示形態についてより多くをコントロールでき、画面がロックされているかどうかによらない一貫した操作感をユーザーに提供できます。
+
+
+</p>
+
+<h3 style="clear:both"
+id="dialogs_and_toasts_are_for_feedback_not_notification">ダイアログとトースト
+</h3>
+
+<p>アプリが画面上に表示されていないときにダイアログやトーストを作成しないようにしてください。
+ダイアログやトーストの表示は、アプリでのアクションに対するユーザーへの即座の応答のみにします。ダイアログやトーストの使用の目安については、<a href="/design/patterns/confirming-acknowledging.html">確認と通知</a>をご覧ください。
+
+
+
+</p>
+
+<h3>評価と並べ替え</h3>
+
+<p>通知はニュースであるため、基本的には新しい順に表示され、アプリが通知に指定した<a href="#correctly_set_and_manage_notification_priority">優先度</a>に基づき特別な配慮がなされます。
+
+
+</p>
+
+<p>通知はロック画面の重要な一部であり、端末のディスプレイがオンになるたび前面に出ます。
+
+ロック画面のスペースは限られているため、もっとも緊急か重要な通知を識別することが何より重要になります。
+
+この理由から、Android では洗練された通知並べ替えアルゴリズムを採用しており、その中で以下を考慮しています。
+
+</p>
+
+<ul>
+ <li> タイムスタンプと、アプリが指定した優先度。</li>
+ <li> その通知が最近ユーザーに音または振動で配信されたかどうか。
+(つまり、電話が音を立てるだけの場合、ユーザーが「何が起こったのか」を知りたくなったら、ロック画面はそれに一目でわかる答えを示すべきです)。
+
+
+</li>
+ <li> {@link android.app.Notification#EXTRA_PEOPLE} を使用して通知に添付された人、特にその人が「お気に入り」の連絡先かどうか。
+</li>
+</ul>
+
+<p>この並べ替え機能を最大限に生かすには、リストにおける特定の位置付けを狙うのではなく、ユーザーの操作感に注目します。
+
+</p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/AntiSample3.png" alt="" width="700px" />
+
+ <p class="img-caption" style="margin-top:10px">Gmail 通知の優先度はデフォルトであり、そのため Hangouts などのインスタントメッセージ アプリからのメッセージの下に並びますが、新しいメッセージが来たときは一時的にそれより先に表示されます。
+
+
+
+
+ </p>
+
+
+<h3>ロック画面上</h3>
+
+<p>通知はロック画面に表示されるため、ユーザーのプライバシーはとりわけ重要な考慮対象です。
+
+通知には機密性の高い情報が含まれることが多く、端末を手に取ってディスプレイをオンにした誰にでも見られるようにすべきではありません。
+
+</p>
+
+<ul>
+ <li> セキュリティ保護されたロック画面(PIN、パターン、パスワードなど)を持つ端末の場合、インターフェースには公開部分と秘密部分があります。
+公開インターフェースはセキュリティ保護されたロック画面に表示でき、誰でも見られます。
+秘密インターフェースはロック画面の背後にある世界で、ユーザーが端末にサインインして初めて表示されます。
+</li>
+</ul>
+
+<h3>セキュリティ保護されたロック画面に表示される情報のユーザー コントロール</h3>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/LockScreen@2x.png" srcset="{@docRoot}images/android-5.0/notifications/LockScreen.png 1x" alt="" width="311px" />
+ <p class="img-caption">
+ ロック画面上の通知。コンテンツはユーザーが端末をロック解除した後に表示されます。
+ </p>
+</div>
+
+<p>セキュリティ保護されたロック画面をセットアップする際、ユーザーはセキュリティ保護されたロック画面には表示しない機密性の高い情報を選ぶことができます。
+その場合、システム UI は通知の<em>可視性レベル</em>を考慮して、表示しても問題ない情報を識別します。
+
+</p>
+<p> 可視性レベルをコントロールするには、<code><a
+href="/reference/android/app/Notification.Builder.html#setVisibility(int)">Notification.Builder.setVisibility()</a></code> を呼び出し、次の値のどれかを指定します。
+
+</p>
+
+<ul>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_PUBLIC">VISIBILITY_PUBLIC</a></code>。通知の内容がすべて表示されます。
+
+ 可視性レベルが指定されていない場合は、これがシステム デフォルトです。</li>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_PRIVATE">VISIBILITY_PRIVATE</a></code>。ロック画面に、その通知の存在に関する基本情報、たとえば通知のアイコンやそれを提示したアプリ名などを表示します。
+
+通知のその他の詳細は表示されません。いくつか留意すべき点があります。
+
+ <ul>
+ <li> システムがセキュリティ保護されたロック画面に表示するためとして公開バージョンの通知を別に提供する場合は、<code><a
+href="/reference/android/app/Notification.html#publicVersion">Notification.publicVersion</a></code> フィールドに代替 Notification オブジェクトを用意します。
+
+
+
+ <li> この設定により、アプリは利便性はあるが個人情報は明かさない編集されたバージョンのコンテンツを作成できるようになります。
+SMS アプリを例に考えて見ましょう。通知には SMS のテキストメッセージ、送信者の名前、連絡先アイコンが含まれています。この通知は <code>VISIBILITY_PRIVATE</code> であるべきですが、<code>publicVersion</code> にも "3 件の新しいメッセージ" のような個人を特定する詳細なしでも利便性のある情報を盛り込めます。
+
+
+
+
+ </ul>
+ </li>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_SECRET">Notification.VISIBILITY_SECRET</a></code>。必要最小限の情報のみ表示し、通知のアイコンさえありません。
+</li>
+</ul>
+<h2 style="clear:both" id="notifications_on_android_wear">Android Wear での通知
+</h2>
+
+<p>通知とそのアクション<em></em>は、デフォルトで Wear 端末にブリッジされます。デベロッパーは、どの通知が電話から腕時計へ、またはその逆へブリッジするかを制御できます。
+
+
+また、どのアクションがブリッジするかも制御できます。タップ 1 回では完了しないアクションがアプリに含まれている場合は、そうしたアクションを Wear 通知では隠すか Wear アプリに接続することを検討してください。いずれにしても、ユーザーがアクションを腕時計で完了できるようにします。
+
+
+
+
+
+</p>
+
+<h4>通知とアクションのブリッジ</h4>
+
+<p>電話のような接続状態の端末は、通知を Wear 端末にブリッジして、通知が腕時計に表示されるようにできます。
+同様に、アクションもブリッジして、ユーザーが通知に Wear 端末で直接対処できるようにできます。
+</p>
+
+<p><strong>ブリッジする</strong></p>
+
+<ul>
+ <li> 新しいインスタントメッセージ</li>
+ <li> +1、いいね、心拍数のようなタップ 1 回のアクション</li>
+</ul>
+
+<img src="{@docRoot}images/android-5.0/notifications/WearBasic.png" width="156px" height="156px" alt="" />
+
+<p><strong>ブリッジしない</strong></p>
+
+<ul>
+ <li> 新着ポッドキャストの通知</li>
+ <li> 腕時計ではできない機能にマップされたアクション</li>
+</ul>
+
+
+
+<p><h4>Wear 専用に定義されたアクション</h4></p>
+
+<p>Wear でのみできるアクションがいくつかあります。次に例を挙げます。</p>
+
+<ul>
+ <li> 「Be right back」 のような定形応答のクイックリスト</li>
+ <li> 携帯電話で開く</li>
+ <li> 音声入力画面を起動する 「Comment」 アクションや 「Reply」 アクション</li>
+ <li> Wear 専用アプリを起動するアクション</li>
+</ul>
+
+<img src="{@docRoot}images/android-5.0/notifications/ReplyAction.png" width="156px" height="156px" alt="" />
diff --git a/docs/html-intl/intl/ja/preview/api-overview.jd b/docs/html-intl/intl/ja/preview/api-overview.jd
new file mode 100644
index 0000000..2c0816b
--- /dev/null
+++ b/docs/html-intl/intl/ja/preview/api-overview.jd
@@ -0,0 +1,521 @@
+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">Assist API</a></li>
+ <li><a href="#notifications">通知</a></li>
+ <li><a href="#bluetooth-stylus">Bluetooth スタイラスのサポート</a></li>
+ <li><a href="#ble-scanning">Bluetooth Low Energy のスキャンの改善</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">API レベル 22 から M Preview&raquo;</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>M Developer Preview では、ユーザーやアプリ開発者に Android プラットフォームの次期リリースの新機能をいち早く試していただくことができます。
+
+このドキュメントでは、いくつかの注目すべき API の概要について説明します。</p>
+
+<p>M Developer Preview は、<strong>Developer の早期導入者</strong>と<strong>テスター</strong>を対象としています。
+是非
+<a href="{@docRoot}preview/setup-sdk.html">M Developer Preview を試して</a>フィードバックをご提供ください。あなたのご意見が、Android フレームワークの方向性を決定する上で貴重な情報になります。
+
+</p>
+
+<p class="caution"><strong>注意:</strong> M Developer Preview を使用したアプリは、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">Behavior Changes</a> をご覧ください。</p>
+
+<h2 id="app-linking">アプリのリンク機能</h2>
+<p>このプレビューでは、アプリのリンク機能を強化することで Android のインテント システムが向上しました。この機能では、所有するウェブドメインにアプリを関連付けることができます。
+この関連付けに基づいて、プラットフォームが特定のウェブリンクの処理に使用するデフォルトのアプリを決めることができ、ユーザーにアプリを選択させる操作をスキップできます。この機能の実装方法については、
+<a href="{@docRoot}preview/features/app-linking.html">アプリのリンク機能</a>をご覧ください。
+
+
+
+<h2 id="backup">アプリの自動バックアップ</h2>
+<p>システムで、アプリの自動フルデータ バックアップと復元を実行できるようになりました。この動作は、M Preview を対象としたアプリでデフォルトで有効になっています。追加のコードは必要ありません。
+ユーザーが 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 キーストローク システム</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 Tools Revision 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>ユーザーが正常に認証された後、同じキーを再使用できるタイムアウト期間を設定するには、{@link javax.crypto.KeyGenerator} か
+{@link java.security.KeyPairGenerator} のセットアップ後に新しい
+{@code android.security.keystore.KeyGenParameterSpec.setUserAuthenticationValidityDurationSeconds()} メソッドを呼び出します。
+
+現在、この機能は対象暗号化操作で動作します。
+</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 "android.service.chooser.chooser_target_service"} という名前の
+{@code &lt;meta-data&gt;} 要素をアプリのマニフェストに追加します。
+
+</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>
+このプレビューでは、<a href="https://developers.google.com/voice-actions/" class="external-link">音声アクション</a>と共に使用することでアプリに対話形式の音声操作をビルドできる新しい音声インタラクション API が提供されます。
+
+
+{@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">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>新しい<em>アラームのみの</em> Do not disturb モードに相当する新しい {@code NotificationListenerService.INTERRUPTION_FILTER_ALARMS} フィルタレベル。
+</li>
+ <li>ユーザーが予定したリマインダを他のイベント({@link android.app.Notification#CATEGORY_EVENT})やアラーム({@link android.app.Notification#CATEGORY_ALARM})から区別する際に使用される新しい{@code Notification.CATEGORY_REMINDER} カテゴリの値。
+
+
+</li>
+ <li>{@code Notification.Builder.setSmallIcon(Icon)} メソッドや {@code Notification.Builder.setLargeIcon(Icon)} メソッド経由で通知にアタッチできる新しい {@code android.graphics.drawable.Icon} クラス。
+
+</li>
+ <li>現在どの通知がアクティブなのかをアプリが検出できるようにする新しい {@code NotificationManager.getActiveNotifications()} メソッド。
+この機能を使用するアプリの実装については、<a href="https://github.com/googlesamples/android-ActiveNotifications" class="external-link">アクティブな通知のサンプル</a>をご覧ください。
+</li>
+</ul>
+
+<h2 id="bluetooth-stylus">Bluetooth スタイラスのサポート</h2>
+<p>このプレビューでは、Bluetooth スタイラスを使用したユーザー入力のサポートが強化されました。互換性のある Bluetooth スタイラスと電話やタブレットをペアリングして接続できます。
+接続されている間、タッチスクリーンからの位置情報とスタイラスからの筆圧やボタン情報を合わせることで、タッチスクリーン単独の場合よりも表現の幅が大きく広がります。
+
+新しい
+{@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 Preview を対象としたアプリでは、ユーザーがプライマリのスタイラス ボタンを押すと
+{@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">Bluetooth Low Energy のスキャンの改善</h2>
+<p>
+アプリで Bluetooth Low Energy スキャンを実行する場合は、新しい
+{@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 Release 1 仕様のサポートが追加されました。アクセス ポイント 2.0 の資格情報をアプリに提供するには、
+{@code setPlmn()} や {@code setRealm()} などの
+{@link android.net.wifi.WifiEnterpriseConfig} クラスの新しいメソッドを使用します。
+{@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 Preview を実行する端末で、テーマの属性が
+{@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()} メソッドを呼び出します。
+これらのメソッドは、{@link android.support.v4.content.ContextCompat} の v4 appcompat ライブラリにもあります。
+</p>
+
+<h2 id="audio">オーディオ機能</h2>
+
+<p>このプレビューでは、次のように Android でのオーディオ処理が改善されました。 </p>
+<ul>
+ <li>新しい {@code android.media.midi} API を使った <a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a> プロトコルのサポート。
+これらの API を使用して MIDI イベントを送受信できます。
+</li>
+ <li>デジタル オーディオの録音を作成して、それぞれのオブジェクトを再生し、システムのデフォルトをオーバーライドするオーディオ ソースとシンク プロパティを構成するための新しい {@code android.media.AudioRecord.Builder} クラスと {@code android.media.AudioTrack.Builder} クラス
+
+。</li>
+ <li>オーディオと入力端末を関連付ける API フック。これは、ユーザーが 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()} メソッドを呼び出すことで、カメラ端末を開かずにフラッシュ ユニットのタッチモードのオン/オフを切り替えることができます。
+アプリには、フラッシュ ユニットやカメラ端末のフラッシュの独占所有権はありません。
+トーチモードは、カメラ端末が利用不可になったときや、トーチを付けている他のカメラリソースが利用不可になったときにオフになり、利用できなくなります。
+
+他のアプリでも {@code setTorchMode()} を呼び出してトーチモードをオフにできます。
+最後にトーチモードをオンにしたアプリが閉じられると、トーチモードはオフになります。
+</p>
+
+<p>
+{@code CameraManager.registerTorchCallback()} メソッドを呼び出すことで、トーチモードの状態に関する通知を受けるようコールバックを登録できます。コールバックを初めて登録したときに、現在検知されているすべてのフラッシュ ユニット付きのカメラ端末のトーチモードの状態が即座に呼び出されます。
+
+トーチモードが正常にオン/オフされると、
+{@code CameraManager.TorchCallback.onTorchModeChanged()} メソッドが呼び出されます。</p>
+
+<h3 id="reprocessing">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} 出力画像の循環的な画像のキューを維持でき、1 つ以上の画像を選択して、それらをカメラの再処理用に
+{@code ImageWriter} に送ることができます。</p>
+
+<h2 id="afw">Android for Work の機能</h2>
+<p>このプレビューには、次のような Android for Work 用の新しい API が含まれています。</p>
+<ul>
+ <li><strong>企業の専用端末の制御の強化:</strong>デバイス オーナーは次の設定を制御でき、企業の専用端末を管理しやすくなります。
+
+
+ <ul>
+ <li>
+{@code DevicePolicyManager.setKeyguardEnabledState()} メソッドを使ったキーガードの無効化と有効化。</li>
+ <li>
+{@code DevicePolicyManager.setStatusBarEnabledState()} メソッドを使ったステータスバー(クイック設定、通知、Google Now を起動するスワイプアップのジェスチャ)の無効化と有効化。
+</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>デバイス オーナーでは、{@link android.content.pm.PackageInstaller} API を使って、Google Play for Work から独立してアプリケーションをサイレントにインストール、アンインストールできます。
+
+デバイス オーナー経由で、ユーザー操作なしでアプリを取得したりインストールしたりできる端末を提供できます。
+この機能は、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 日間保留したりできます。
+
+さらに、管理者はアップデートを実行する時間枠を、キオスク端末が使用されていない時間帯などに設定できます。
+利用可能なシステムアップデートがある場合、システムは Work Policy Controller アプリにシステムアップデートのポリシーがあるかどうかを確認し、それに基づいて動作します。
+
+
+</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)をロック解除するようパラメータを構成できます。
+NFC プログラマー アプリでは、端末が FRP のロック解除するようリセットされ、端末がプロビジョニングされた後にこれらのパラメータを提供でき、事前に Google アカウントを設定しておく必要はありません。
+
+これらのパラメータを修正しない場合、FRP は続行し、事前にアクティブ化された Google の資格情報なしで端末がアクティベートされないようにします。
+
+
+<p>さらに、Google Play サービスでアプリの制限を設定することで、デバイス オーナーは FRP のロック解除用の別の Google アカウントを指定して、端末でアクティベートされたアカウントを置き換えることができます。
+</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 Developer Preview のすべての API の変更点の詳細については、<a href="{@docRoot}preview/download.html">API Differences Report</a> をご覧ください。
+</p>
diff --git a/docs/html-intl/intl/ja/preview/behavior-changes.jd b/docs/html-intl/intl/ja/preview/behavior-changes.jd
new file mode 100644
index 0000000..a7950a1
--- /dev/null
+++ b/docs/html-intl/intl/ja/preview/behavior-changes.jd
@@ -0,0 +1,402 @@
+page.title=動作の変更点
+page.keywords=プレビュー,sdk,compatibility
+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">App Standby</a></li>
+ </ol>
+ </li>
+ <li><a href="#behavior-adoptable-storage">追加可能なストレージ端末</a></li>
+ <li><a href="#behavior-apache-http-client">Apache HTTP Client の削除</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">API レベル 22 から M Preview&raquo;</a> </li>
+</ol>
+
+
+<h2>関連ドキュメント</h2>
+<ol>
+<li><a href="{@docRoot}preview/api-overview.html">M Developer Preview API の概要</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>M Developer Preview には、新機能以外にもさまざまなシステムの変更点や API の動作の変更点が盛り込まれています。
+このドキュメントでは、アプリ開発において把握しておくべき主な変更点について説明します。
+</p>
+
+<p>過去に Android にアプリを公開したことがある場合は、アプリがこれらの変更による影響を受ける場合があることに注意してください。
+</p>
+
+<h2 id="behavior-runtime-permissions">実行時パーミッション</h1>
+<p>このプレビューでは、アプリのパーミッションを実行時にユーザーが直接管理できる新しいパーミッション モデルが採用されました。
+このモデルによって、ユーザーに対するパーミッションの可視性と制御性が向上し、アプリ開発者にとってはアプリのインストールや自動アップデート プロセスの効率が上がります。ユーザーはインストール済みアプリのパーミッションを個別に付与したり取り消したりできます。
+
+ </p>
+
+<p>M Preview を対象としたアプリでは、必ずパーミッションを実行時に確認、要求するようにします。
+アプリにパーミッションが付与されているかどうかを確認するには、新しい {@code Context.checkSelfPermission()} メソッドを呼び出します。
+パーミッションを要求するには、新しい
+{@code Activity.requestPermission()} メソッドを呼び出します。アプリが M を対象としていない場合でも、新しいパーミッション モデルでアプリをテストするようにしてください。
+</p>
+
+<p>アプリで新しいパーミッションをサポートする際の詳細については、Developer Preview ページの
+<a href="{@docRoot}preview/features/runtime-permissions.html">Permissions</a> をご覧ください。
+アプリへの影響を評価する際のヒントについては、<a href="{@docRoot}preview/testing/guide.html#runtime-permissions">Testing Guide</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 Messaging の通知を受信する場合以外、ネットワーク アクセスは無効になります。
+</li>
+<li><a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">Wake ロック</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 Preview を実行する端末を開発マシンに接続して、次のコマンドを呼び出します。
+
+</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 Messaging</a> の次期リリースでは、高優先度のメッセージを指定できます。
+
+アプリが高優先度の GCM メッセージを受信する場合は、端末が Doze 中でも短時間のネットワーク アクセスが付与されます。
+
+</p>
+
+<p>アプリで Doze をテストする方法のヒントについては、
+<a href="{@docRoot}preview/testing/guide.html#doze-standby">Testing Guide</a> をご覧ください。
+ </p>
+
+<h3 id="behavior-app-standby">App Standby</h3>
+<p>このプレビューでは、アクティブに使用されていないアプリをシステムがアイドル状態であるとみなす場合があります。
+システムが次の信号を検出しない場合、一定時間の経過後にアプリはアイドル状態であるとみなされます。
+</p>
+
+<ul>
+<li>アプリがユーザーによって明示的に起動された。</li>
+<li>アプリのプロセスが現在フォアグラウンドにある(アクティビティかフォアグラウンド サービスとしてか、他のアクティビティかフォアグラウンド サービスによって使用されている)。
+</li>
+<li>アプリがロック画面や通知トレイに表示される通知を生成する。
+</li>
+<li>ユーザーが、アプリに最適化が適用されないよう <strong>[設定]</strong> で明示的に指定する。
+</li>
+</ul>
+
+<p>端末が電源に接続されていない場合、アイドル中のみなされたアプリのネットワーク アクセスは無効になり、同期とジョブは保留されます。
+端末が電源に接続されると、アプリのネットワーク アクセスは許可され、保留中のすべてのジョブと同期が実行されます。
+端末が長時間アイドル状態の場合、アイドル中のアプリは 1 日 1 回程度ネットワーク アクセスが許可されます。
+</p>
+
+<p>この機能をテストするには、M Preview を実行する端末を開発マシンに接続して、次のコマンドを呼び出します。
+
+</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 Messaging</a>(GCM)の次期リリースでは、高優先度のメッセージを指定できます。
+
+アプリが高優先度の GCM メッセージを受信する場合は、アプリがアイドル 中でも短時間のネットワーク アクセスが付与されます。
+
+</p>
+
+<p>アプリで App Standby をテストする方法のヒントについては、
+<a href="{@docRoot}preview/testing/guide.html#doze-standby">Testing Guide</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>Developer Preview のこの機能をデバッグするには、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 Client の削除</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 を使用している場合は、{@code libcrypto.so} や {@code libssl.so} など、NDK API の一部でない暗号化ライブラリにリンクしないでください。
+これらのライブラリは パブリック 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 Support Library</a> revision 22.2 を使用している場合、フローティング ツール バーに下方互換性はなく、デフォルトで appcompat が代わりに {@link android.view.ActionMode} オブジェクトを制御することに注意してください。
+
+これにより、フローティング ツール バーは表示されなくなります。
+{@link android.support.v7.app.AppCompatActivity} で
+{@link android.view.ActionMode} がサポートされるようにするには、
+{@code android.support.v7.app.AppCompatActivity.getDelegate()} を呼び出して、返された
+{@link android.support.v7.app.AppCompatDelegate} オブジェクトで
+{@code android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled()} を呼び出し、 入力パラメータを {@code false} に設定します。
+この呼び出して、{@link android.view.ActionMode} オブジェクトの制御がフレームワークに戻ります。
+M Preview を実行する端末ではフレームワークによる
+{@link android.support.v7.app.ActionBar} やフローティング ツール バー モードのサポートが可能ですが、M Preview 以前の端末では
+{@link android.support.v7.app.ActionBar} モードのみがサポートされます。</p>
+
+<h2 id="behavior-keystore">Android キーストロークの変更点</h2>
+<p>このプレビューでは、
+<a href="{@docRoot}training/articles/keystore.html">Android Keystore プロバイダ</a>による DSA のサポートがなくなります。
+ECDSA は引き続きサポートされます。</p>
+
+<p>停止時に暗号化を必要としないキーが、ロック画面の(ユーザーや端末の管理者などによる)無効時やリセット時に削除されなくなりました。
+停止時に暗号化を必要とするキーは、これらのイベント時に削除されます。
+</p>
+
+<h2 id="behavior-network">Wi-Fi とネットワークの変更点</h2>
+
+<p>このプレビューでは、Wi-Fi API とネットワーク API の動作に次のような変更点が追加されました。</p>
+<ul>
+<li>オブジェクトの作成者である場合のみ、アプリで{@link android.net.wifi.WifiConfiguration} オブジェクトの状態を変更できます。
+ユーザーや他のアプリによって作成された
+{@link android.net.wifi.WifiConfiguration} オブジェクトは変更、削除できません。
+</li>
+<li>
+以前は、
+{@link android.net.wifi.WifiManager#enableNetwork(int,boolean) enableNetwork()} で
+{@code disableAllOthers=true} 設定を使ってアプリから端末を特定の Wi-Fi ネットワークに接続させた場合、端末はセルラー データなどの他のネットワークから切断されていました。
+このプレビューでは、端末が他のネットワークから切断されないようになりました。アプリの {@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>
+現在のユーザーを変更すると、アプリ内で前のユーザー アカウントで所有していたアクティブなカメラ クライアントが中断させられることになります。
+カメラへのアクセスは、現在の端末ユーザーが所有するユーザー プロファイルのみに制限されます。つまり、ユーザーが別のアカウントに切り替えた場合、"ゲスト" アカウントはカメラのサブシステムを使用するプロセスを実行したまま去ることはできません。
+
+
+</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">
+public bug 6670</a>)の違いを認識でき、{@code soname} が実装されています。
+
+
+以前動作していたアプリで間違った {@code DT_NEEDED} エントリを持つもの(ビルドマシンのファイル システムの絶対パスなど)は、読み込み時に失敗する場合があります。
+</p>
+
+<p>{@code dlopen(3) RTLD_LOCAL} フラグは正常に実装されました。
+{@code RTLD_LOCAL} はデフォルトのため、
+{@code RTLD_LOCAL} を明示的に使用しない {@code dlopen(3)} への呼び出しは影響を受けます(アプリで明示的に {@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 は破損しているとみなされます。
+コンテンツが一部でも削除された場合は、APK の再署名が必要になります。
+</p>
+
+<h2 id="behavior-afw">Android for Work の変更点</h2>
+<p>このプレビューには、次のような Android for Work に関する動作の変更点が含まれています。</p>
+<ul>
+<li><strong>個人のコンテキストでの仕事用の連絡先</strong>ユーザーが過去の通話履歴を表示したときに、Google Dialer
+Call Log に仕事用の連絡先が表示されるようになりました。{@code DevicePolicyManager.setCrossProfileCallerIdDisabled()} を {@code true} に設定すると、Google Dialer Call Log に仕事用プロファイルの連絡先は表示されなくなります。
+
+{@code DevicePolicyManager.setBluetoothContactSharingDisabled()} を {@code false} に設定した場合のみ、Bluetooth 経由で端末に仕事用の連絡先と個人用の連絡先を表示できます。
+
+デフォルトでは、{@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 設定は、ユーザーが修正したり削除したりできなくなりました。
+ユーザーに {@link android.os.UserManager} 定数
+{@link android.os.UserManager#DISALLOW_CONFIG_WIFI} が設定されていない限り、ユーザー自身の WiFi 設定を作成、修正することはできます。
+</li>
+<li><strong>Google アカウントの追加経由での Work Policy Controller のダウンロード:</strong>Work Policy Controller(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/ja/preview/features/runtime-permissions.jd b/docs/html-intl/intl/ja/preview/features/runtime-permissions.jd
new file mode 100644
index 0000000..f582756
--- /dev/null
+++ b/docs/html-intl/intl/ja/preview/features/runtime-permissions.jd
@@ -0,0 +1,794 @@
+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 Preview 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 Developer Preview では、アプリをインストールしてアップグレードするユーザーのプロセスを効率化する新しいアプリのパーミッション モデルが導入されました。
+M Preview で実行しているアプリで新しいパーミッション モデルがサポートされている場合、ユーザーはアプリをインストールまたはアップグレードするときにパーミッションを付与する必要はありません。その代わりに、アプリは必要になるとパーミッションを要求し、パーミッションを確認するよう求めるダイアログが表示されます。
+
+
+
+
+</p>
+
+<p>
+ アプリで新しいパーミッション モデルがサポートされている場合、以前のバージョンの Android を実行している端末で、以前のパーミッション モデルを使ってインストールして実行することもできます。
+
+
+</p>
+
+<h2 id="overview">
+ 概要
+</h2>
+
+<p>
+ M Developer Preview とともに、プラットフォームでは新しいアプリのパーミッション モデルが導入されました。
+この新しいモデルの主要なコンポーネントの概要を次に示します。
+</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 Developer Preview の場合、新しいパーミッション モデルを使う<em>必要があります</em>。
+
+</p>
+
+<p>
+ M Developer Preview のローンチ時点では、すべての Google アプリで新しいパーミッション モデルが完全に実装されているわけではありません。
+Google はこれらのアプリを M Developer Preview 中にアップデートして、パーミッションの切り替え設定を完全に実装します。
+
+
+</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>アプリ</strong>] &gt; <i>[app_name]</i> &gt; [<strong>パーミッション</strong>] を選ぶと、いつでもパーミッションを取り消すことができます。アプリは実行時にパーミッションを継続して確認し、必要に応じて要求する必要があります。
+
+
+</p>
+
+<h3 id="compatibility">
+ 上方互換と下方互換
+</h3>
+
+<p>
+ アプリのターゲットが M Developer Preview 以外の場合、M Preview 端末でも以前のパーミッション モデルを引き続き使います。
+ユーザーがアプリをインストールするとき、ユーザーはアプリのマニフェストでリストされているすべてのパーミッションを付与するように要求されます。
+
+
+</p>
+
+<p class="note">
+ <strong>注:</strong> M Developer Preview を実行している端末で、ユーザーはアプリの [設定] 画面から従来のアプリを含むすべてのアプリのパーミッションをオフにできます。
+
+従来のアプリに対してパーミッションをオフにすると、適切な機能がサイレント状態で無効になります。
+アプリがそのパーミッションを必要とする操作を実行しようとするとき、その操作によって必ずしも例外が発生するとは限りません。
+
+代わりに、空のデータセットを返す、エラーを示す、または予期しない動作を返すことがあります。
+たとえば、パーミッションなしでカレンダーを照会すると、メソッドは空のデータセットを返します。
+
+</p>
+
+<p>
+ M Preview を実行していない端末で新しいパーミッション モデルを使ってアプリをインストールする場合、他のすべてのアプリと同様に扱われ、インストール時に、すべての宣言されたパーミッションを付与するようユーザーに求めます。
+
+
+
+</p>
+
+<p class="note">
+ <strong>注:</strong> Preview リリースの場合、M Preview SDK に SDK の最小バージョンを設定して Preview SDK でコンパイルする必要があります。
+つまり、Developer Preview 中は従来のプラットフォームでそのようなアプリをテストできません。
+
+
+</p>
+
+<h3 id="perms-vs-intents">パーミッションとインテント</h3>
+
+<p>
+ 多くの場合、アプリがタスクを実行するには 2 つの方法から選択できます。
+アプリ自体が操作を実行するパーミッションを要求できます。
+アプリでインテントを使うようにして、別のアプリがそのタスクを実行するようにすることもできます。
+
+</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 Developer Preview の場合、新しいパーミッション モデルを使う必要があります。
+つまり、マニフェストで必要なパーミッションを宣言する他に、実行時にパーミッションがあることを確認し、まだパーミッションがない場合にはパーミッションを要求します。
+
+
+
+</p>
+
+<h3 id="enabling">
+ 新しいパーミッション モデルを有効にする
+</h3>
+
+<p>
+ 新しい M Developer Preview パーミッション モデルを有効にするには、アプリの <code>targetSdkVersion</code> 属性を <code>"MNC"</code> に、<code>compileSdkVersion</code> を <code>"android-MNC"</code> に設定します。
+
+このように設定することで、新しいパーミッション機能すべてが有効になります。
+
+</p>
+
+<p>
+ Preview リリースの場合、<code>minSdkVersion</code> を <code>"MNC"</code> に設定して Preview SDK でコンパイルする必要があります。
+
+</p>
+
+<h3 id="m-only-perm">
+ M Preview のみに対するパーミッションの設計
+</h3>
+
+<p>
+ アプリ マニフェストで新しい <code>&lt;uses-permission-sdk-m&gt;</code> 要素を使って、M Developer Preview のみで必要なパーミッションを表示できます。
+このようにしてパーミッションを宣言すると、アプリを以前の端末にインストールする場合はユーザーにメッセージが表示されないか、アプリにパーミッションが付与されません。<code>&lt;uses-permission-sdk-m&gt;</code> 要素を使うと、新しいパーミッションを追加してインストールをアップデートするときにパーミッションの付与を強制せずにアプリのバージョンがアップデートされます。
+
+
+
+
+
+
+</p>
+
+<p>
+ M Developer Preview を使ってアプリが端末で実行されている場合、<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 Developer Preview パーミッション モデルが使われている場合、M Preview を実行している端末でアプリを初めて起動するとき、すべての権限を付与する必要はありません。
+
+その代わりに、アプリは必要なときにパーミッションを要求します。
+アプリがパーミッションを要求すると、ユーザーにダイアログが表示されます。
+
+</p>
+
+<p>
+ SDK 22 以降がインストールされた端末でアプリを実行する場合、アプリでは以前のパーミッション モデルが使われます。
+ユーザーがアプリをインストールすると、アプリがそのマニフェストで要求するすべてのパーミッションの付与を求めるメッセージが表示されます。ただし、<code>&lt;uses-permission-sdk-m&gt;</code> というラベルの付いたパーミッションは例外です。
+
+
+</p>
+
+<h4 id="check-platform">アプリが実行されているプラットフォームを確認する</h4>
+
+<p>
+ このパーミッション モデルは、M Developer Preview を実行している端末でのみサポートされます。
+これらのメソッドのいずれかを呼び出す前に、アプリは {@link android.os.Build.VERSION#CODENAME
+ Build.VERSION.CODENAME} の値を確認してどのプラットフォーム上で実行されているのかを確認する必要があります。
+
+端末で M Developer Preview が実行されている場合、{@link android.os.Build.VERSION#CODENAME CODENAME} は <code>"MNC"</code> です。
+
+</p>
+
+<h4 id="check-for-permission">アプリに必要なパーミッションがあるかどうかを確認する</h4>
+
+<p>ユーザーがパーミッションを要求する動作を行うと、アプリは現在この操作を実行するためのパーミッションがあるかどうかを確認します。
+
+
+確認するために、アプリは <code>Context.checkSelfPermission(<i>permission_name</i>)</code> を呼び出します。ユーザーが既にパーミッションを付与していることをアプリが認識している場合でも、ユーザーはいつでもアプリのパーミッションを取り消すことができるため、この確認が行われます。
+
+
+たとえば、ユーザーがアプリを使って写真を撮る場合、アプリは <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 Developer Preview の場合、パーミッションが正しく処理されることをテストする必要があります。
+アプリ起動時に特定のパーミッションがアプリにあることは想定できません。
+アプリが初めて起動されるとき、パーミッションがない可能性が高く、ユーザーはいつでもパーミッションを取り消すまたは復元できます。
+
+
+</p>
+
+<p>
+ アプリがすべてのパーミッションの状況下で確実に正しく動作することをテストしてください。
+M Preview SDK とともに、新しい <a href="{@docRoot}tools/help/adb.html">Android デバッグ ブリッジ(adb)</a>コマンドが導入され、試す必要のあるあらゆるパーミッション設定でアプリをテストできます。
+
+
+
+</p>
+
+<h3>
+ 新しい adb コマンドとオプション
+</h3>
+
+<p>
+ M Preview SDK Platform-tools では、アプリがパーミッションをどう処理するかをテストするための、いくつかの新しいコマンドが導入されました
+
+</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">Package Manager(pm)</a>コマンドを使って、インストールされているアプリにパーミッションを付与したり取り消したりできます。この機能は自動化されたテストに役立ちます。
+
+
+</p>
+
+<p>
+ パーミッションを付与するには、Package Manager の <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>
+ パーミッションを取り消すには、Package Manager の <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>
+ アプリ対して 1 つ以上のパーミッションが必須である場合もあります。その場合は、アプリの起動後すぐに、すべてのパーミッションを要求することが合理的である場合があります。
+
+たとえば、カメラアプリを作成する場合、アプリは端末のカメラにアクセスする必要があります。
+アプリを初めて起動するときにカメラの使用についてのパーミッションを求められても驚かないはずです。
+
+ただし、同じアプリにユーザーの連絡先と写真を共有する機能もある場合は、最初の起動時にパーミッションを要求<em>しない</em>方が無難です。
+
+その代わりに、ユーザーが「共有」機能を使うまで待ち、そのときにパーミッションを要求します。
+
+</p>
+
+<p>
+ アプリにチュートリアルが含まれる場合は、チュートリアルのシーケンスの最後で、アプリに必須のパーミッションを要求する方が合理的です。
+
+</p>
+
+<h3 id="bp-explain">
+ パーミッションが必要な理由を説明する
+</h3>
+
+<p>
+ <code>requestPermissions()</code> を呼び出すとき、システムによって表示されるパーミッション ダイアログにはアプリが必要としているパーミッションは表示されますが、理由は表示されません。
+
+これによりユーザーが困惑する場合もあります。
+ <code>requestPermissions()</code> を呼び出す前に、アプリがパーミッションを必要としている理由をユーザーに説明するのはよい方法です。
+
+</p>
+
+<p>
+ たとえば、カメラアプリでは、位置情報サービスを使って写真に位置情報タグを付けられるようにする場合があります。
+通常のユーザーは、写真に位置情報が含まれる場合があることを認識していない可能性があり、なぜカメラアプリで位置情報が必要なのか困惑する可能性があります。
+
+この場合、アプリが <code>requestPermissions()</code> を呼び出す<em>前</em>に、この機能についてユーザーに知らせることをお勧めします。
+
+
+</p>
+
+<p>
+ その方法として、これらの要求をアプリのチュートリアルに組み込むこともできます。チュートリアルでは、アプリの各機能を順番に表示できるので、必要なパーミッションを説明できます。
+
+たとえば、カメラアプリのチュートリアルでは、「連絡先と写真を共有する」機能について説明し、ユーザーの連絡先を参照するためにアプリにパーミッションが必要であることをユーザーに知らせることができます。
+
+
+その後、アプリは <code>requestPermissions()</code> を呼び出して、ユーザーにそのアクセスを求めることができます。
+もちろん、すべてのユーザーがチュートリアルに従うわけではないため、アプリの通常操作中にパーミッションを確認して要求することも必要です。
+
+
+</p>
diff --git a/docs/html-intl/intl/ja/preview/overview.jd b/docs/html-intl/intl/ja/preview/overview.jd
new file mode 100644
index 0000000..4cefdd1
--- /dev/null
+++ b/docs/html-intl/intl/ja/preview/overview.jd
@@ -0,0 +1,362 @@
+page.title=プログラム概要
+page.metaDescription=Android M Developer Preview では、Android の次のバージョンでアプリをテストして最適化するためのすべてを備えています。
+page.image=images/cards/card-preview_16-9_2x.png
+page.tags="preview", "developer", "android"
+
+@jd:body
+
+<p>
+ <strong>Android M Developer Preview</strong> では、Android の次のバージョンでアプリをテストして最適化するためのすべてを備えています。
+
+M Developer Preview ツールをダウンロードするだけで、無料ですぐにご利用いただけます。
+
+</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、Nexus Player(TV 向け)やエミュレータでアプリをテストしましょう。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 最新プラットフォーム コード
+ </h5>
+
+ <p>
+ プレビューで複数のアップデートが提供されますので、最新プラットフォームの変更に応じてテストできます。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ OTA でのアップデート
+ </h5>
+
+ <p>
+ デバイスに初期プレビューをコピーしたら、無線経由でアップデートを入手できます。
+
+ </p>
+ </div>
+ </div>
+
+ <div class="cols">
+
+
+ <div class="col-4of12">
+ <h5>
+ 新しい動作と機能
+ </h5>
+
+ <p>
+ 新しい実行時パーミッション モデルや省電力機能など、新しいプラットフォームの動作をあらかじめサポートする
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 開発者が報告した問題に対する優先度ウィンドウ
+ </h5>
+
+ <p>
+ 最初の数週間で開発者から報告のあった問題について優先度を設定し、可能な限り早くテストを行いフィードバックを提供できるようにします。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ フィードバックとサポート
+ </h5>
+
+ <p>
+ <a href="https://code.google.com/p/android-developer-preview/">Issue Tracker</a> で問題を報告し、フィードバックをお送りください。
+ <a href="http://g.co/dev/AndroidMDevPreview">M&nbsp;Developer コミュニティ</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 Developer Preview は 5 月 28 日から最終の Android M SDK まで実行されます。Android M SDK はまもなく、2015 年第三四半期に予定されている正式公開の前にリリースされます。
+
+
+</p>
+
+<p>
+ 開発の主なマイルストーンごとにテスト端末へアップデートを配信する予定としています。
+ 暫定マイルストーンは以下のとおりです。
+</p>
+
+<ul>
+ <li>
+ <strong>Preview&nbsp;1</strong>(初期プレビュー リリース、5 月下旬)
+ </li>
+
+ <li>
+ <strong>Preview&nbsp;2</strong>(6 月下旬/7 月上旬)
+ </li>
+
+ <li>
+ <strong>Preview&nbsp;3</strong>(最終近く、7 月下旬)
+ </li>
+</ul>
+
+<p>
+ アップデートは第三四半期後半に予定されている<strong>最終 SDK</strong> で終了します。最終版では新しい Android に対する正式な API や最終的なシステム動作や機能が提供されます。
+
+
+</p>
+
+<p>
+ Android M でのテストや開発に際しては、Preview アップデートがリリースされるたびに<strong>開発環境を最新に保つ</strong>ことを強くお勧めします。
+
+ プロセスをより容易にするため、既に Preview ビルドがインストールされた端末に<strong>無線経由でアップデート(OTA)</strong>を配信します。また手動でダウンロードして展開できるシステム イメージもご提供します。
+
+
+</p>
+<p class="note">
+ <strong>注:</strong> 最終 SDK とシステム イメージは OTA では配信できません。代わりにテスト端末に<strong>手動でコピー</strong>する必要があります。</strong>
+
+
+</p>
+
+<p>
+ Preview アップデートをご利用いただけるようになった際は <a href="http://android-developers.blogspot.com/">Android デベロッパー ブログ</a>、このサイト、<a href="http://g.co/dev/AndroidMDevPreview">Android M デベロッパー コミュニティ</a>でお知らせします。
+
+
+</p>
+
+<h2 id="preview_tools">
+ Preview の内容
+</h2>
+
+<p>
+ M Developer Preview では、ご利用のアプリをさまざまな画面サイズ、ネットワーク、テクノロジー、CPU や GPU チップセット、ハードウェア設計でテストするために必要なあらゆるものを備えています。
+
+
+</p>
+
+<h4>
+ SDK ツール
+</h4>
+
+<p>
+ 各コンポーネントは <a href="{@docRoot}sdk/installing/adding-packages.html">Android Studio</a> の SDK Manager でダウンロードできます。
+</p>
+
+<ul>
+ <li>M Developer Preview <strong>SDK ツール</strong>
+ </li>
+
+ <li>M Developer Preview <strong>エミュレータ システム イメージ</strong>(32 ビット版と 64 ビット版)
+
+ </li>
+
+ <li>M Developer Preview <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>(AndroidTV)“fugu” 端末システム イメージ
+ </li>
+</ul>
+
+<h4>
+ ドキュメントとサンプル コード
+</h4>
+
+<p>
+ 次のドキュメント リソースで Preview についての詳細をご確認いただけます。
+</p>
+
+<ul>
+ <li>
+ <a href="setup-sdk.html">SDK のセットアップ</a>では、はじめの手順をステップ バイ ステップでご説明しています。
+
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/testing/guide.html">Testing Guide</a> と <a href="behavior-changes.html">Behavior Changes</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 Developer Preview の変更メモや差分レポートなどをご覧いただけます。
+
+ </li>
+</ul>
+
+<h4>
+ サポート リソース
+</h4>
+
+<p>
+ M Developer Preview でのテストや開発について、次のサポート リソースをご確認いただけます。
+
+</p>
+
+<ul>
+ <li><a href="https://code.google.com/p/android-developer-preview/">M Developer Preview Issue Tracker</a> は、<strong>主なフィードバック チャンネル</strong>としてご利用になれます。
+
+バグやパフォーマンスの問題、一般的なフィードバックなど Issue Tracker からご連絡いただけます。
+また、<a href="https://code.google.com/p/android-developer-preview/wiki/KnownIssues">既知の問題</a>
+やその回避策をご確認いただけます。
+ </li>
+
+ <li><a href="http://g.co/dev/AndroidMDevPreview">Android M Developer コミュニティ</a>は Google+ のコミュニティで、Android M を使っている<strong>他のデベロッパーとつながる</strong>ことができます。Android M に関する現象や考えを共有したり、疑問点を解消したりできます。
+
+
+
+ </li>
+</ul>
+
+
+<h2 id="preview_apis_and_publishing">
+ 対象、プレビュー API、公開
+</h2>
+
+<p>
+ Android M Developer Preview は開発リリースのみであり、<strong>標準 API レベルはありません</strong>。
+アプリのテストで互換性の問題は除外する場合(強く推奨します)、アプリの<code><a href=
+ "/guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a></code> を <code>“MNC”</code> に設定することで M Developer Preview を対象にできます。
+
+
+
+</p>
+
+<p>
+ Android M Developer Preview では<strong>プレビュー API</strong> を配信しています。現在 2015 年度第三四半期に予定されている最終 SDK がリリースされるまで、API は正式版ではありません。
+
+つまり、時間がたつにつれて <strong>API の細かな変更</strong>が見込まれます(特にプログラムの最初の数週間)。
+
+Android M Developer Preview でアップデートがあればその都度変更の概要をご提供します。
+
+</p>
+
+<p class="note">
+ プレビュー API は変更される可能性がありますが、実行時パーミッションや省電力機能などのシステムの基幹にかかわる機能には変更はありませんので、すぐにテストしていただけます。
+
+
+</p>
+
+<p>
+ 公開に関して、Google Play では <strong>M Developer Preview 対象アプリは公開できません</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">Behavior Changes</a> で新しい機能やご自分のアプリへの影響についてご確認ください。
+
+特に、<a href="{@docRoot}preview/features/runtime-permissions.html">実行時パーミッション</a> モデルや省電力機能、自動バックアップ機能についてお確かめください。
+
+
+ </li>
+
+ <li><a href="{@docRoot}preview/setup-sdk.html">Setting up the Preview SDK</a> の手順に従い、ご利用の環境をセットアップしてテスト端末を構成してください。
+
+
+ </li>
+
+ <li><a href="https://developers.google.com/android/nexus/images">コピー手順</a>に従い、最新の M Developer Preview システム イメージを Nexus 5、6、9、Nexus Player にコピーします。
+
+1 度開発端末に Preview 環境をコピーすると、アップデートが無線経由(OTA)で配信されます。</a>
+
+ </li>
+
+ <li><a href="{@docRoot}preview/download.html#docs">M Preview API リファレンス</a>や<a href="{@docRoot}preview/samples.html">M Preview サンプル</a>をダウンロードして、新しい API の機能についてさらに学び、ご自分のアプリで活用する方法についてご確認ください。
+
+
+
+ </li>
+
+ <li><a href="http://g.co/dev/AndroidMDevPreview">Android M Developer コミュニティ</a>に参加して最新のニュースを入手し、Preview に取り組んでいる他のデベロッパーとつながってください。
+
+
+ </li>
+</ol>
+
+<p>
+ Android M Developer Preview プログラムへのご参加ありがとうございます。
+</p>
diff --git a/docs/html-intl/intl/ja/training/basics/activity-lifecycle/index.jd b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/index.jd
new file mode 100644
index 0000000..837fc2b
--- /dev/null
+++ b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/index.jd
@@ -0,0 +1,72 @@
+page.title=アクティビティのライフサイクル 管理
+page.tags=アクティビティのライフサイクル
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+
+<h2>必要な知識と前提条件</h2>
+<ul>
+ <li>Android プロジェクトの作成方法(<a href="{@docRoot}training/basics/firstapp/creating-project.html">Android
+プロジェクトの作成</a>を参照)</li>
+</ul>
+
+
+<h2>関連ドキュメント</h2>
+<ul>
+ <li><a href="{@docRoot}guide/components/activities.html">アクティビティ</a></li>
+</ul>
+
+
+<h2>試してみる</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">デモのダウンロード</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>ユーザーがアプリ内を移動したり、アプリ外に移動したり、再びアプリに戻ったりすると、アプリの
+{@link android.app.Activity} インスタンスが、それらのライフサイクルの異なる状態間で遷移します。
+たとえば、アクティビティが新規に開始されると、システムのフォアグラウンドに表示され、ユーザーに認識されるようにします。
+
+このプロセスの間に、Android システムは、ユーザー インターフェースやその他のコンポーネントが設定されたアクティビティ上で一連のライフサイクル メソッドを呼び出します。
+ユーザーが別のアクティビティを開始する、または別のアプリに切り替えるアクションを実行した場合、システムはアクティビティ上で別の一連のライフサイクル メソッドを呼び出し、アクティビティがバックグラウンドに移動します(この場合、アクティビティが表示されなくなりますが、インスタンスとその状態はそのまま維持されます)。
+
+
+</p>
+
+<p>ライフサイクル コールバック メソッドでは、ユーザーがアクティビティを離れたり、再開させたりした場合のアクティビティの動作について宣言することができます。
+たとえば、ストリーミング ビデオ プレーヤーをビルドしている場合、ユーザーが別のアプリに切り替えた際にビデオを一時停止したり、ネットワーク接続を終了することが可能です。ユーザーが戻った場合には、ネットワークに再接続し、一時停止した場所からビデオを再開できるようにすることができます。
+
+
+</p>
+
+<p>このクラスでは、各 {@link
+android.app.Activity} インスタンスが受け取る重要なライフサイクル コールバック メソッドについて、またそれらを使用してユーザーが期待する内容でアクティビティを動作させる方法、アクティビティがそれらを必要としないときにシステムのリソースを消費しないようにする方法について学習します。
+</p>
+
+<h2>レッスン</h2>
+
+<dl>
+ <dt><b><a href="starting.html">アクティビティを開始する</a></b></dt>
+ <dd>アクティビティのライフサイクルに関する基本、ユーザーがアプリを起動する方法、基本的なアクティビティ作成の方法について学習します。
+</dd>
+ <dt><b><a href="pausing.html">アクティビティの一時停止と再開</a></b></dt>
+ <dd>アクティビティが一時停止状態(部分的に不可視)および、再開された場合の動作、そしてこれらの状態の変遷時に何をすべきかについて学習します。
+</dd>
+ <dt><b><a href="stopping.html">アクティビティの停止と再起動</a></b></dt>
+ <dd>ユーザーが完全にアクティビティから移動し、その後戻ってきた場合の動作について学習します。</dd>
+ <dt><b><a href="recreating.html">アクティビティを再作成する</a></b></dt>
+ <dd>アクティビティが破棄されるときの動作と、必要に応じてアクティビティの状態を再構築する方法について学習します。
+</dd>
+</dl>
+
diff --git a/docs/html-intl/intl/ja/training/basics/activity-lifecycle/pausing.jd b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/pausing.jd
new file mode 100644
index 0000000..b837a00
--- /dev/null
+++ b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/pausing.jd
@@ -0,0 +1,147 @@
+page.title=アクティビティの一時停止と再開
+page.tags=アクティビティのライフサイクル
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>このレッスンでの学習内容</h2>
+ <ol>
+ <li><a href="#Pause">アクティビティを一時停止する</a></li>
+ <li><a href="#Resume">アクティビティを再開する</a></li>
+ </ol>
+
+ <h2>関連ドキュメント</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">アクティビティ</a>
+ </li>
+ </ul>
+
+<h2>試してみる</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">デモのダウンロード</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>通常のアプリの使用中、フォアグラウンドのアクティビティは、他のビジュアル コンポーネントによって隠される場合があり、これによりアクティビティが<em>一時停止</em>します。
+たとえば、半透明のアクティビティが開くと(ダイアログのスタイルなど)、以前のアクティビティは一時停止します。
+そのアクティビティは、まだ部分的に表示されていても、現在フォーカスされているアクティビティではない状態である限り、一時停止状態が維持されます。
+</p>
+
+<p>ただし、アクティビティが完全に隠され、表示されなくなった場合は、<em>停止</em>します(これについては次のレッスンで説明します)。
+</p>
+
+<p>アクティビティが一時停止状態に入ると、一時停止中は継続させない方が望ましい進行中のアクション(ビデオなど)を停止させたり、ユーザーがアプリを離れたままになった場合に備えて保存する必要のある情報すべてを保持したりできるよう、システムは {@link android.app.Activity} 上で {@link
+android.app.Activity#onPause onPause()} メソッドを呼び出します。ユーザーが一時停止状態からアクティビティに復帰した場合は、システムはアクティビティを再開し、{@link android.app.Activity#onResume onResume()} メソッドを呼び出します。
+
+
+
+</p>
+
+<p class="note"><strong>注:</strong> アクティビティが {@link
+android.app.Activity#onPause()} の呼び出しを受信した場合は、アクティビティが一瞬一時停止された後、ユーザーが同アクティビティにフォーカスを戻す可能性があることを示している場合があります。
+ただし、通常は、ユーザーがアクティビティを離れていることを最初に示すものです。
+</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-paused.png" />
+<p class="img-caption"><strong>図 1.</strong>半透明のアクティビティによって自分のアクティビティが隠されると、システムは {@link android.app.Activity#onPause onPause()} を呼び出し、アクティビティは一時停止の状態で待機します(1)。
+
+一時停止中にユーザーがアクティビティに復帰した場合、システムは {@link android.app.Activity#onResume onResume()} を呼び出します(2)。
+</p>
+
+
+<h2 id="Pause">アクティビティを一時停止する</h2>
+
+<p>システムがアクティビティに対して {@link android.app.Activity#onPause()} を呼び出した場合、技術的にはアクティビティはまだ部分的に表示されていることを意味しますが、ほとんどの場合は、ユーザーがアクティビティを離れていて、ほどなく停止状態になる徴候を示しています。
+
+通常、以下を行う場合には、{@link android.app.Activity#onPause()} コールバックを使用する必要があります。
+</p>
+
+<ul>
+ <li>CPU を消費する可能性があるアニメーションや他の進行中のアクションを停止する。</li>
+ <li>ユーザーがアクティビティを離れた場合にも変更が永続的に保存されると期待するような場合(メールの下書きなど)でのみ、未保存の変更をコミットする。
+</li>
+ <li>放送用レシーバーなどのシステム リソース、(GPS
+などの)センサー処理や、アクティビティが一時停止され、ユーザーが必要としない間にバッテリー寿命に影響を与える可能性があるすべてのリソースを解放する。
+</li>
+</ul>
+
+<p>たとえば、アプリケーションが {@link android.hardware.Camera} を使用する場合、{@link android.app.Activity#onPause()} メソッドは、リソースの解放に適した手段です。
+</p>
+
+<pre>
+&#64;Override
+public void onPause() {
+ super.onPause(); // Always call the superclass method first
+
+ // Release the Camera because we don't need it when paused
+ // and other activities might need to use it.
+ if (mCamera != null) {
+ mCamera.release()
+ mCamera = null;
+ }
+}
+</pre>
+
+<p>一般的には、(フォームに入力された個人情報などの)ユーザーの変更を永続的なストレージに保存する目的の場合には、{@link android.app.Activity#onPause()} の使用は<strong>避ける</strong>必要があります。
+特定のユーザーが(メールの下書きのように)変更の自動保存を期待していると確信できる場合のみ、{@link android.app.Activity#onPause()}の期間内に永続的なストレージにユーザーの変更を保持する必要があります。ただし、{@link
+android.app.Activity#onPause()} メソッド中にはデータベースへの書き込みなどの CPU に高負荷をかける作業を行うことは避けてください。これにより、次のアクティビティへの表示上の遷移を遅らせる可能性があります(代わりに
+{@link android.app.Activity#onStop onStop()} メソッド中に高負荷のシャットダウン操作を実行する必要があります)。
+
+
+
+</p>
+
+<p>{@link android.app.Activity#onPause
+onPause()} メソッドで実行される処理量を比較的シンプルに抑えて、アクティビティが実際に停止している場合にユーザーの次の移動先への迅速な遷移を可能にする必要があります。
+</p>
+
+<p class="note"><strong>注:</strong> アクティビティが一時停止されると、{@link
+android.app.Activity} インスタンスはメモリに常駐し、アクティビティが再開されたときに再び呼び出されます。再開状態に導くいずれかのコールバック メソッドの間に作成されたコンポーネントを再初期化する必要はありません。
+
+</p>
+
+
+
+<h2 id="Resume">アクティビティを再開する</h2>
+
+<p>ユーザーが一時停止状態からアクティビティを再開した場合、システムは、{@link
+android.app.Activity#onResume()} メソッドを呼び出します。</p>
+
+<p>新規に作成された場合を含め、アクティビティがフォアグラウンドに表示されるたびに、システムがこのメソッドを呼び出すことに注意してください。
+したがって、{@link
+android.app.Activity#onPause()} メソッド中に解放したコンポーネントの初期化、およびアクティビティが再開状態になるたびに発生するその他の初期化(アニメーションの開始や、アクティビティがユーザーのフォーカスを取得したときにのみ使用されるコンポーネントの初期化など)を実行するように、{@link
+android.app.Activity#onResume()} を実装する必要があります。
+
+</p>
+
+<p>{@link android.app.Activity#onResume()} に関する次の例は、上記の
+{@link android.app.Activity#onPause()} に関する例に対応するものであり、アクティビティが一時停止したときに解放されたカメラ機能を初期化します。
+</p>
+
+<pre>
+&#64;Override
+public void onResume() {
+ super.onResume(); // Always call the superclass method first
+
+ // Get the Camera instance as the activity achieves full user focus
+ if (mCamera == null) {
+ initializeCamera(); // Local method to handle camera init
+ }
+}
+</pre>
+
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/ja/training/basics/activity-lifecycle/recreating.jd b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/recreating.jd
new file mode 100644
index 0000000..8647375
--- /dev/null
+++ b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/recreating.jd
@@ -0,0 +1,178 @@
+page.title=アクティビティを再作成する
+page.tags=アクティビティのライフサイクル
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>このレッスンでの学習内容</h2>
+ <ol>
+ <li><a href="#SaveState">自分のアクティビティ状態を保存する</a></li>
+ <li><a href="#RestoreState">自分のアクティビティ状態をリストアする</a></li>
+ </ol>
+
+ <h2>関連ドキュメント</h2>
+ <ul>
+ <li><a href="{@docRoot}training/basics/supporting-devices/screens.html">異なる画面のサポート
+</a></li>
+ <li><a href="{@docRoot}guide/topics/resources/runtime-changes.html">実行時の変更を処理する</a></li>
+ <li><a href="{@docRoot}guide/components/activities.html">アクティビティ</a>
+ </li>
+ </ul>
+
+ </div>
+</div>
+
+<p>アクティビティには、通常のアプリの動作によって破棄されるいくつかのシナリオがあります。たとえば、ユーザーが <em>[戻る]</em> ボタンを押したり、アクティビティが {@link android.app.Activity#finish()} を呼び出すことによって自身の破棄を知らせる場合などです。
+
+システムはまた、現在停止していて長時間使用されていないアクティビティがある場合や、フォアグラウンドのアクティビティが多くのリソースを必要とするためにシステムがメモリを取り戻すためにバックグラウンド プロセスを停止する必要がある場合にも、アクティビティを破棄することがあります。
+
+</p>
+
+<p>ユーザーが <em>[戻る]</em> を押すか、アクティビティ自身が終了することでアクティビティが破棄されたとき、これらの動作はアクティビティの必要性がなくなったことを示すため、システムの方針として {@link android.app.Activity} インスタンスは永遠に失われます。
+
+システムの制約(通常のアプリの動作ではなく)が原因で
+アクティビティが破棄される場合、実際の
+{@link android.app.Activity} インスタンスは失われますが、アクティビティが存在していたことをシステムが記憶しているため、ユーザーがアクティビティに復帰した場合は、破棄されたときのアクティビティの状態を記述する一連の保存されたデータを使用して、アクティビティの新しいインスタンスが作成されます。
+
+システムが以前の状態を復元するために使用する保存されたデータは、「インスタンス状態」と呼ばれ、{@link android.os.Bundle} オブジェクトに格納されたキーと値のペアの集合です。
+
+</p>
+
+<p class="caution"><strong>警告: </strong>ユーザーが画面を回転させるたびに、アクティビティが破棄され、再作成されます。
+画面の向きが変更されると、画面構成が変更され、アクティビティで(レイアウトなどの)代替リソースをロードする必要が生じる場合があるため、システムはフォアグラウンドのアクティビティを破棄し、再作成します。
+
+</p>
+
+<p>デフォルトでは、システムは {@link android.os.Bundle} のインスタンス状態を使用して、アクティビティのレイアウトの各 {@link android.view.View} オブジェクトに関する情報を保存しています({@link android.widget.EditText} オブジェクトに入力されたテキスト値など)。
+
+アクティビティのインスタンスが破棄され、再作成される場合、レイアウトの状態はコードを必要とすることなく以前の状態に復元されます。
+
+しかし、アクティビティでは、アクティビティにおけるユーザーの作業状況を追跡しているメンバ変数などの、復元することが望ましいその他の情報が存在する可能性があります。
+
+</p>
+
+<p class="note"><strong>注:</strong> Android システムがアクティビティのビューの状態を復元できるようにするためには、<strong>各ビューは固有の ID を持っている必要があります</strong>。これは
+ <a href="{@docRoot}reference/android/view/View.html#attr_android:id">{@code
+android:id}</a> によって提供されます。
+</p>
+
+<p>アクティビティ状態についての追加データを保存するには、
+{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} コールバック メソッドをオーバーライドする必要があります。システムは、ユーザーがアクティビティを離れようとするとこのメソッドを呼び出し、{@link android.os.Bundle} オブジェクトに渡してアクティビティが予期せずに破棄された場合に備えて保存します。
+
+
+システムが後でアクティビティのインスタンスを再作成する必要がある場合は、同じ {@link
+android.os.Bundle} オブジェクトを {@link android.app.Activity#onRestoreInstanceState
+onRestoreInstanceState()} と {@link android.app.Activity#onCreate onCreate()}
+ の両方のメソッドに渡します。
+</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-savestate.png" />
+<p class="img-caption"><strong>図 2.</strong> システムがアクティビティを停止し始めると、
+{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}(1)が呼び出されるため、{@link android.app.Activity} インスタンスの再作成の必要がある場合に備えて、保存する追加の状態データを指定できます。アクティビティが破棄され、同じインスタンスを再作成する必要がある場合、システムは(1)で定義された状態データを {@link android.app.Activity#onCreate onCreate()} メソッド(2)と
+{@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} メソッド(3)の両方に渡します。
+
+
+
+
+</p>
+
+
+
+<h2 id="SaveState">自分のアクティビティ状態を保存する</h2>
+
+<p>アクティビティが停止し始めると、システムは {@link android.app.Activity#onSaveInstanceState
+onSaveInstanceState()} を呼び出すため、アクティビティではキー値のペアのコレクションを使用して、状態情報を保存することができます。
+このメソッドのデフォルトの実装では、{@link android.widget.EditText} ウィジェット内のテキストまたは {@link android.widget.ListView} のスクロール位置などのアクティビティのビュー階層の状態に関する情報が保存されます。
+
+</p>
+
+<p>アクティビティの追加の状態情報を保存するには、
+{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} を実装し、{@link android.os.Bundle} オブジェクトにキー値のペアを追加する必要があります。
+次に例を示します。</p>
+
+<pre>
+static final String STATE_SCORE = "playerScore";
+static final String STATE_LEVEL = "playerLevel";
+...
+
+&#64;Override
+public void onSaveInstanceState(Bundle savedInstanceState) {
+ // Save the user's current game state
+ savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
+ savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
+
+ // Always call the superclass so it can save the view hierarchy state
+ super.onSaveInstanceState(savedInstanceState);
+}
+</pre>
+
+<p class="caution"><strong>警告: </strong>デフォルトの実装でビュー階層の状態を保存できるよう、{@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()} のスーパークラスの実装を常に呼び出す必要があります。
+</p>
+
+
+
+<h2 id="RestoreState">自分のアクティビティ状態をリストアする</h2>
+
+<p>以前破棄された後にアクティビティが再作成される場合、システムがアクティビティを渡した先の {@link android.os.Bundle} から、保存済みの状態を回復することができます。
+
+{@link android.app.Activity#onCreate onCreate()} と {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} の両方のコールバック メソッドが、インスタンスの状態情報を含む同じ {@link android.os.Bundle} を受け取ります。
+</p>
+
+<p>{@link android.app.Activity#onCreate onCreate()} メソッドは、システムがアクティビティの新しいインスタンスを作成しているか、以前のものを復元しているかどうかに関係なく呼び出されるため、状態の {@link android.os.Bundle} を読み取る前にこれが null かどうかを確認する必要があります。
+
+null の場合は、破棄された以前のアクティビティを復元する代わりにアクティビティの新しいインスタンスが作成されます。
+
+</p>
+
+<p>{@link android.app.Activity#onCreate
+onCreate()} で、いくつかの状態データを復元する方法について、次に例を示します。</p>
+
+<pre>
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState); // Always call the superclass first
+
+ // Check whether we're recreating a previously destroyed instance
+ if (savedInstanceState != null) {
+ // Restore value of members from saved state
+ mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
+ mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
+ } else {
+ // Probably initialize members with default values for a new instance
+ }
+ ...
+}
+</pre>
+
+<p>{@link android.app.Activity#onCreate onCreate()} 中に状態を復元する代わりに、
+{@link android.app.Activity#onStart()} メソッドの後に呼び出される {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} の実装を選択できます。
+復元対象の保存済みの状態がある場合のみ {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} が呼び出されるため、
+{@link android.os.Bundle} が null であるかどうかをチェックする必要はありません。</p>
+
+<pre>
+public void onRestoreInstanceState(Bundle savedInstanceState) {
+ // Always call the superclass so it can restore the view hierarchy
+ super.onRestoreInstanceState(savedInstanceState);
+
+ // Restore state members from saved instance
+ mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
+ mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
+}
+</pre>
+
+<p class="caution"><strong>警告: </strong>デフォルトの実装でビュー階層の状態を復元できるよう、{@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} のスーパークラスの実装を常に呼び出す必要があります。
+</p>
+
+<p>実行時の再起動イベント(画面が回転したときなど)によるアクティビティの再作成の詳細については、<a href="{@docRoot}guide/topics/resources/runtime-changes.html">実行時の変更を処理する</a>をお読みください。
+</p>
+
diff --git a/docs/html-intl/intl/ja/training/basics/activity-lifecycle/starting.jd b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/starting.jd
new file mode 100644
index 0000000..7c865a9
--- /dev/null
+++ b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/starting.jd
@@ -0,0 +1,285 @@
+page.title=アクティビティを開始する
+page.tags=アクティビティのライフサイクル
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>このレッスンでの学習内容</h2>
+<ol>
+ <li><a href="#lifecycle-states">ライフサイクル コールバックを理解する</a></li>
+ <li><a href="#launching-activity">アプリのランチャーのアクティビティを指定する</a></li>
+ <li><a href="#Create">新しいインスタンスを作成する</a></li>
+ <li><a href="#Destroy">アクティビティを破棄する</a></li>
+</ol>
+
+ <h2>関連ドキュメント</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">アクティビティ</a></li>
+ </ul>
+
+<h2>試してみる</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">デモのダウンロード</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>{@code main()} メソッドを使用してアプリを起動する他のプログラミング パラダイムとは異なり、Android システムでは、そのライフサイクルの特定の段階に対応する特定のコールバック メソッドを呼び出すことによって、{@link android.app.Activity} インスタンスでコードを開始します。
+
+
+アクティビティを起動するコールバック メソッドのシーケンスと、アクティビティを破棄するコールバック メソッドのシーケンスがあります。
+</p>
+
+<p>このレッスンでは、最も重要なライフサイクル メソッドの概要を示し、アクティビティの新しいインスタンスを作成する最初のライフサイクル コールバックを扱う方法について説明します。
+</p>
+
+
+
+<h2 id="lifecycle-states">ライフサイクル コールバックを理解する</h2>
+
+<p>アクティビティの存続期間において、システムは、階段ピラミッド型のシーケンスで、ライフサイクル メソッドのコア セットを呼び出します。
+つまり、アクティビティのライフサイクルの各段階は、ピラミッドの個別の段です。
+システムが新しいアクティビティのインスタンスを作成すると、各コールバック メソッドはアクティビティ状態を 1 ステップ上に向かって移動させます。
+ピラミッドの頂点は、アクティビティがフォアグラウンドで実行されるポイントであり、ユーザーはそこで操作を行うことができます。
+</p>
+
+<p>ユーザーがアクティビティを離れる操作を始めると、システムはアクティビティを破棄するために、アクティビティ状態をピラミッドの下に向かって移動させる、別のメソッドを呼び出します。
+アクティビティがピラミッドの下に向かって途中まで移動し、待機する場合がありますが(ユーザーが別のアプリに切り替えた場合など)、そのポイントからアクティビティは頂点に戻ることができ(ユーザーがアクティビティに戻った場合)、アクティビティはユーザーが離れた場所から再開します。
+
+
+</p>
+
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle.png" />
+<p class="img-caption"><strong>図 1.</strong> アクティビティのライフサイクルの簡略図は階段ピラミッドとして表現されます。
+ここでは、アクティビティを頂点の再開状態に向かって 1 ステップ移動させるために使用されるすべてのコールバックに対して、下に向かってアクティビティを移動させるコールバック メソッドがどのように分布しているかを示しています。
+
+アクティビティはまた、一時停止や停止の状態から再開した状態に復帰することができます。
+</p>
+
+
+<p>アクティビティの複雑さにもよりますが、すべてのライフサイクルメソッドを実装する必要はありません。
+ただし、それぞれを理解して、自分のアプリがユーザーの期待どおり動作するよう実装することが重要です。
+アクティビティのライフサイクル メソッドを正しく実装すると、自分のアプリが次を含めたいくつかの状態で良好に動作するようになります。
+</p>
+<ul>
+ <li>アプリの使用中にユーザーが電話を受けたり、別のアプリに切り替えた場合にもクラッシュしません。
+</li>
+ <li>ユーザーの使用頻度が低いときは、貴重なシステムリソースを消費しません。
+</li>
+ <li>ユーザーがアプリから離れ、後で復帰した場合でも、アプリを離れた時点における作業状態を失いません。
+</li>
+ <li>画面の向きが横長と縦長との間で切り替わったときも、クラッシュしたり、ユーザーの作業内容が失われることがありません。
+</li>
+</ul>
+
+<!--
+<p class="table-caption"><strong>Table 1.</strong> Activity lifecycle state pairs and callback
+methods.</p>
+<table>
+ <tr>
+ <th scope="col">Lifecycle State</th>
+ <th scope="col">Startup Method</th>
+ <th scope="col">Teardown Method</th>
+ </tr>
+ <tr>
+ <td>Created / Destroyed</td>
+ <td>{@link android.app.Activity#onCreate onCreate()}</td>
+ <td>{@link android.app.Activity#onDestroy()}</td>
+ </tr>
+ <tr>
+ <td>Started / Stopped</td>
+ <td>{@link android.app.Activity#onStart()}</td>
+ <td>{@link android.app.Activity#onStop()}</td>
+ </tr>
+ <tr>
+ <td>Resumed / Resumed</td>
+ <td>{@link android.app.Activity#onResume()}</td>
+ <td>{@link android.app.Activity#onPause()}</td>
+ </tr>
+</table>
+-->
+
+<p>次のレッスンで学習するように、図 1 に示されているさまざまな状態間で起きるアクティビティ遷移には、いくつかの状況があります。
+ただし、これらの状態のうち 3 つのみが静的なものとなります。
+すなわち、アクティビティが長期間にわたる場合、3 つの状態のいずれかで存在することになります。
+</p>
+<dl>
+ <dt>再開状態</dt>
+ <dd>この状態では、アクティビティがフォアグラウンドで実行され、ユーザーはそこで操作を行うことができます(「実行」状態とも呼ばれます)。
+</dd>
+ <dt>一時停止状態</dt>
+ <dd>この状態では、アクティビティは別のアクティビティによって部分的に隠されています。フォアグラウンドにある別のアクティビティは半透明になっているか、全画面をカバーしていません。
+一時停止したアクティビティはユーザーの入力を受信せず、一切のコードを実行できません。
+
+ <dt>停止状態</dt>
+ <dd>この状態では、アクティビティは完全に隠され、ユーザーには表示されません。バックグラウンドに存在するとみなされます。
+停止状態の間、アクティビティ インスタンスとメンバ変数のようなそのすべての状態情報は保持されますが、アクティビティ インスタンスは一切のコードを実行できません。
+</dd>
+</dl>
+
+<p>他の状態(作成や起動の状態)は一過性であり、システムはすぐに次のライフサイクル コールバック メソッドを呼び出して、次の状態に移動します。
+つまり、システムは
+{@link android.app.Activity#onCreate onCreate()} を呼び出した後、すぐに {@link
+android.app.Activity#onStart()} を呼び出しますが、この後で速やかに {@link
+android.app.Activity#onResume()} が続きます。</p>
+
+<p>以上が、アクティビティの基本ライフサイクルです。次に、特定のライフサイクルの動作のいくつかについて学習を開始しましょう。
+</p>
+
+
+
+<h2 id="launching-activity">アプリのランチャー アクティビティを指定する</h2>
+
+<p>ユーザーがホーム画面からアプリのアイコンを選択すると、システムはアプリ内で「ランチャー」(または「メイン」)のアクティビティであると宣言された {@link android.app.Activity} に対して {@link
+android.app.Activity#onCreate onCreate()} メソッドを呼び出します。
+これは、アプリのユーザー インターフェースへのメインのエントリ ポイントとして機能するアクティビティです。
+</p>
+
+<p>プロジェクト ディレクトリのルートにある Android のマニフェスト ファイル、<a href="{@docRoot}guide/topics/manifest/manifest-intro.html">{@code AndroidManifest.xml}</a> で、メインのアクティビティとして
+どのアクティビティを使用するが定義することができます。</p>
+
+<p>アプリのメインのアクティビティは、{@link
+android.content.Intent#ACTION_MAIN MAIN} アクションと {@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} カテゴリを含む <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a> を使用してマニフェストで宣言する必要があります。
+次に例を示します。</p>
+
+<pre>
+&lt;activity android:name=".MainActivity" android:label="&#64;string/app_name">
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.MAIN" />
+ &lt;category android:name="android.intent.category.LAUNCHER" />
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p class="note"><strong>注:</strong> Android SDK ツールを使用して新しい Android プロジェクトを作成すると、デフォルトのプロジェクト ファイルに、このフィルタを用いてマニフェストで宣言された {@link android.app.Activity} クラスが含まれます。
+
+</p>
+
+<p>自分のアクティビティの 1 つについて、{@link android.content.Intent#ACTION_MAIN MAIN} アクションまたは
+{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} カテゴリのいずれかが宣言されていない場合は、アプリのアイコンがホーム画面のアプリ リストに表示されません。
+</p>
+
+
+
+<h2 id="Create">新しいインスタンスを作成する</h2>
+
+<p>ほとんどのアプリには、ユーザーが異なるアクションを実行できるようにする、いくつかの異なるアクティビティが含まれます。あるアクティビティが、ユーザーがアプリのアイコンをクリックしたときに作成されるメインのアクティビティであっても、ユーザーのアクションに応答してアプリが開始する別のアクティビティであっても、システムはその {@link
+android.app.Activity#onCreate onCreate()} を呼び出すことにより、{@link android.app.Activity} の新しいインスタンスを毎回作成します。
+
+
+</p>
+
+<p>アクティビティの存続期間すべてにわたり、一度のみ発生すべき基本的なアプリの起動ロジックを実行するための
+{@link android.app.Activity#onCreate onCreate()} メソッドを実装する必要があります。たとえば、
+{@link android.app.Activity#onCreate onCreate()} の実装では、ユーザー インターフェースを定義し、場合によってはいくつかのクラススコープの変数をインスタンス化する必要があります。
+</p>
+
+<p>たとえば、{@link android.app.Activity#onCreate onCreate()}メソッドに関する次の例では、(XML レイアウトファイルで定義される)ユーザー インターフェースを宣言したり、メンバ変数を定義したり、UI の一部を構成したりするなどの、アクティビティ用のいくつかの基本的なセットアップを実行する複数のコードを示しています。
+
+
+</p>
+
+<pre>
+TextView mTextView; // Member variable for text view in the layout
+
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Set the user interface layout for this Activity
+ // The layout file is defined in the project res/layout/main_activity.xml file
+ setContentView(R.layout.main_activity);
+
+ // Initialize member TextView so we can manipulate it later
+ mTextView = (TextView) findViewById(R.id.text_message);
+
+ // Make sure we're running on Honeycomb or higher to use ActionBar APIs
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ // For the main activity, make sure the app icon in the action bar
+ // does not behave as a button
+ ActionBar actionBar = getActionBar();
+ actionBar.setHomeButtonEnabled(false);
+ }
+}
+</pre>
+
+<p class="caution"><strong>警告: </strong>{@link android.os.Build.VERSION#SDK_INT} を使用すると、Android 2.0(API レベル 5)以降でのみこの方法で動作する新しい API が古いシステムで実行してしまうことを回避できます。
+
+古いバージョンでは、実行時の例外が発生します。</p>
+
+<p>{@link android.app.Activity#onCreate onCreate()} の実行が終了すると、システムが引き続き {@link android.app.Activity#onStart()} と {@link android.app.Activity#onResume()} メソッドを呼び出します。
+
+アクティビティは、作成や開始の状態で留まることはありません。技術的には、アクティビティは {@link android.app.Activity#onStart()} が呼び出されたときにユーザーに表示されますが、すぐに
+{@link android.app.Activity#onResume()} が続き、電話の着信やユーザーが別のアクティビティに移動したり、端末の画面がオフになったりした際のように、状態を変える状況が発生するまで、アクティビティは再開状態のままとなります。
+
+
+</p>
+
+<p>この後に続く他のレッスンでは、その他の起動メソッドである {@link
+android.app.Activity#onStart()} と {@link android.app.Activity#onResume()} が一時停止状態または停止状態からアクティビティを再開するために使用された場合、これらのメソッドがアクティビティのライフサイクル中にいかに有用であるかを説明します。
+</p>
+
+<p class="note"><strong>注:</strong> {@link android.app.Activity#onCreate onCreate()}メソッドには、<a href="recreating.html">アクティビティの再作成</a>についての後続のレッスンで説明している <code>savedInstanceState</code> と呼ぶパラメータが含まれています。
+
+</p>
+
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-create.png" />
+<p class="img-caption"><strong>図 2.</strong> アクティビティの新しいインスタンスを作成する際に
+システムが順に呼び出す 3 つの主なコールバックである
+{@link android.app.Activity#onCreate onCreate()}、{@link
+android.app.Activity#onStart()}、{@link android.app.Activity#onResume()} を強調した、アクティビティのライフサイクル構造の別の図です。コールバックのこのシーケンスが完了すると、アクティビティは再開状態に達し、ユーザーは別のアクティビティに切り替えるまではこのアクティビティを操作できます。
+
+</p>
+
+
+
+
+
+
+
+<h2 id="Destroy">アクティビティを破棄する</h2>
+
+<p>アクティビティの最初のライフサイクル コールバックは、{@link android.app.Activity#onCreate
+onCreate()} であり、最終のコールバックは {@link android.app.Activity#onDestroy} です。システムは、アクティビティのインスタンスが完全にシステム メモリから削除される最終的な指示として、アクティビティでこのメソッドを呼び出します。
+
+</p>
+
+<p>ほとんどのアプリでは、このメソッドを実装する必要はありません。なぜなら、ローカルのクラス参照はアクティビティを使用して破棄され、自分のアクティビティでは、{@link
+android.app.Activity#onPause} と {@link android.app.Activity#onStop} の間にほぼすべてのクリーンアップを実行する必要があるからです。
+ただし、アクティビティに、{@link
+android.app.Activity#onCreate onCreate()} の間、または他の長時間実行中のリソースで作成された、正常に閉じないとメモリのリークを引き起こす可能性のあるバックグラウンド スレッドが含まれている場合、{@link
+android.app.Activity#onDestroy} の間にそれらを破棄する必要があります。
+
+</p>
+
+<pre>
+&#64;Override
+public void onDestroy() {
+ super.onDestroy(); // Always call the superclass
+
+ // Stop method tracing that the activity started during onCreate()
+ android.os.Debug.stopMethodTracing();
+}
+</pre>
+
+<p class="note"><strong>注:</strong> ある状況を除くすべての状況では、システムは{@link android.app.Activity#onPause} と {@link
+android.app.Activity#onStop} を呼び出した後に {@link android.app.Activity#onDestroy}を呼び出します。ある状況とは、{@link android.app.Activity#onCreate onCreate()}メソッド内から {@link
+android.app.Activity#finish()} を呼び出したときです。
+
+自分のアクティビティが別のアクティビティを起動するための一時的な意思決定機能として動作する場合のようないくつかのケースでは、{@link
+android.app.Activity#onCreate onCreate()} 内から {@link android.app.Activity#finish()} を呼び出してアクティビティを破棄できます。
+この場合、システムは他のライフサイクルの任意のメソッドを呼び出すことなく、すぐに {@link android.app.Activity#onDestroy} を呼び出します。
+
+</p>
diff --git a/docs/html-intl/intl/ja/training/basics/activity-lifecycle/stopping.jd b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/stopping.jd
new file mode 100644
index 0000000..0007fe6
--- /dev/null
+++ b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/stopping.jd
@@ -0,0 +1,187 @@
+page.title=アクティビティの停止と再起動
+page.tags=アクティビティのライフサイクル
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>このレッスンでの学習内容</h2>
+ <ol>
+ <li><a href="#Stop">アクティビティを停止する</a></li>
+ <li><a href="#Start">アクティビティを開始/再起動する</a></li>
+ </ol>
+
+ <h2>関連ドキュメント</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">アクティビティ</a>
+ </li>
+ </ul>
+
+<h2>試してみる</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">デモのダウンロード</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>アクティビティを適切に停止、再起動することは、アクティビティのライフサイクルにおいて重要なプロセスであり、これによりアプリが常に動作中であり、進捗中の作業が失われないことをユーザーが認識できるようになります。アクティビティを停止して再開させるシナリオの主な例を次に示します。
+
+</p>
+
+<ul>
+ <li>ユーザーが [最近使用したアプリ] ウィンドウを開き、現在のアプリから別のアプリに切り替えると、現在フォアグラウンドにあるアプリのアクティビティが停止します。
+ユーザーがホーム画面のランチャー アイコンまたは [最近使用したアプリ] ウィンドウから復帰した場合は、アクティビティは再起動します。
+</li>
+ <li>ユーザーが新しいアクティビティを開始するアプリ内のアクションを実行します。2 番目のアクティビティが作成されると現在のアクティビティが停止します。
+ユーザーが <em>[戻る]</em> ボタンを押すと、最初のアクティビティが再起動されます。
+</li>
+ <li>ユーザーが自分の携帯電話でアプリの使用中に電話を受けます。</li>
+</ul>
+
+<p>{@link android.app.Activity} クラスでは、{@link
+android.app.Activity#onStop()} と {@link android.app.Activity#onRestart()} の 2 つのライフサイクル メソッドが提供され、アクティビティの停止動作と再起動動作を明確に制御できます。
+UI が部分的に隠されることでわかる一時停止状態とは異なり、停止状態では必ず UI が完全に表示されなくなり、ユーザーのフォーカスが別のアクティビティ(または完全に別個のアプリ)に移ります。
+
+</p>
+
+<p class="note"><strong>注:</strong> {@link android.app.Activity}インスタンスは、停止中にシステム メモリ内に保持されるため、
+{@link android.app.Activity#onStop()} と {@link android.app.Activity#onRestart()} (さらに {@link
+android.app.Activity#onStart()})メソッドを実装する必要がない場合があります。
+比較的単純なほとんどのアクティビティの場合、アクティビティの停止と再起動が問題なく行われるため、現行のアクションを一時停止してシステム リソースから切り離すために {@link
+android.app.Activity#onPause()} を使用するだけでよい場合もあります。
+</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-stopped.png" />
+<p class="img-caption"><strong>図 1.</strong> ユーザーがアクティビティを離れたとき、システムは
+{@link android.app.Activity#onStop onStop()} を呼び出してアクティビティ(1)を停止します。アクティビティが停止している間にユーザーが復帰した場合、システムは {@link android.app.Activity#onRestart onRestart()}
+(2)を呼び出し、すぐに {@link android.app.Activity#onStart onStart()}(3)と {@link
+android.app.Activity#onResume()}(4)が続きます。
+アクティビティを停止させるシナリオによらず、システムは {@link
+android.app.Activity#onStop onStop()} を呼び出す前に、常に {@link android.app.Activity#onPause onPause()} を呼び出すことに注意してください。
+</p>
+
+
+
+<h2 id="Stop">アクティビティを停止する</h2>
+
+<p>アクティビティは {@link android.app.Activity#onStop()} メソッドの呼び出しを受信すると表示されなくなり、ユーザーが使用していない間は必要とされないほぼすべてのリソースが解放されます。
+
+アクティビティが停止すると、システムはそのメモリを取り戻す必要がある場合に、インスタンスを破棄することがあります。
+極端な場合には、システムは、アクティビティの最終段階に当たる {@link android.app.Activity#onDestroy()} コールバックを呼び出すことなく、アプリのプロセスを強制終了する場合があるため、
+{@link android.app.Activity#onStop()} を使用してメモリのリークを引き起こす可能性があるリソースを解放することが重要です。
+</p>
+
+<p>{@link android.app.Activity#onPause onPause()} メソッドが
+{@link android.app.Activity#onStop()} の前に呼び出されますが、データベースに情報を書き込むような、規模が大きく CPU に負荷がかかるシャットダウン操作を実行するためには {@link android.app.Activity#onStop onStop()}を使用する必要があります。
+
+</p>
+
+<p>永続ストレージに下書きのメモの内容を保存する {@link android.app.Activity#onStop onStop()} の実装の例を次に示します。
+</p>
+
+<!-- TODO: Find a better example for onStop, because this kind of thing should probably use a
+separate thread but that's too complicated to show here. -->
+<pre>
+&#64;Override
+protected void onStop() {
+ super.onStop(); // Always call the superclass method first
+
+ // Save the note's current draft, because the activity is stopping
+ // and we want to be sure the current note progress isn't lost.
+ ContentValues values = new ContentValues();
+ values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
+ values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());
+
+ getContentResolver().update(
+ mUri, // The URI for the note to update.
+ values, // The map of column names and new values to apply to them.
+ null, // No SELECT criteria are used.
+ null // No WHERE columns are used.
+ );
+}
+</pre>
+
+<p>アクティビティが停止すると、{@link android.app.Activity} オブジェクトはメモリに常駐し、アクティビティが再開したときに再び呼び出されます。
+再開状態に導くいずれかのコールバック メソッドの間に作成されたコンポーネントを再初期化する必要はありません。
+また、レイアウト内の各 {@link android.view.View} の現在の状態が追跡されます。そのため、ユーザーが {@link android.widget.EditText} ウィジェットにテキストを入力した場合、その内容が保持されるので、それを保存、復元する必要はありません。
+
+
+</p>
+
+<p class="note"><strong>注:</strong> アクティビティが停止している間にシステムにより破棄された場合でも、依然として {@link android.os.Bundle}(ひとまとまりのキー値のペア)の {@link android.view.View} オブジェクト({@link
+android.widget.EditText} のテキストなど)の状態を保持し、ユーザーがアクティビティの同じインスタンスに復帰した場合には、それらを復元します(次の<a href="recreating.html">レッスン</a>では、アクティビティが破棄され、再作成された場合に、その他の状態データを保存するために {@link android.os.Bundle} を使用する方法の詳細について説明します)。
+
+
+</p>
+
+
+
+<h2 id="Start">アクティビティを開始/再起動する</h2>
+
+<p>アクティビティが停止状態からフォアグラウンドに復帰したとき、
+{@link android.app.Activity#onRestart()} の呼び出しを受信します。システムはまた、アクティビティが表示されるたびに(再起動か新規に作成された場合かのいずれか) {@link
+android.app.Activity#onStart()} メソッドを呼び出します。
+ただし、{@link
+android.app.Activity#onRestart()} メソッドはアクティビティが停止状態から再開する場合にのみ呼び出されるため、アクティビティが以前に停止したが破壊されていない場合にのみ必要となる可能性がある、特別な復旧作業を実行するためにこれを使用できます。
+
+</p>
+
+<p>多くの場合、アプリがアクティビティの状態を復元するために {@link android.app.Activity#onRestart()} の使用が必要となることはないため、一般的な多くのアプリに適用されるこのメソッドに関するガイドラインはありません。
+
+ただし、{@link android.app.Activity#onStop()} メソッドは、基本的にアクティビティのすべてのリソースをクリーンアップするため、アクティビティが再起動した際には再インスタンス化する必要があります。
+
+また、アクティビティが新規に作成されたとき(アクティビティの既存のインスタンスがない場合)にも、インスタンス化する必要があります。
+このような理由から、{@link android.app.Activity#onStop()} メソッドへの対応として、通常は {@link android.app.Activity#onStart()} コールバック メソッドを使用する必要があります。なぜなら、アクティビティを作成したときと停止状態からアクティビティを再開したときの両方において、システムが {@link
+android.app.Activity#onStart()} を呼び出すからです。
+
+
+</p>
+
+<p>たとえば、ユーザーが復帰まで長時間アプリから離れている可能性があるため、
+{@link android.app.Activity#onStart()} メソッドは、必要なシステム機能が有効になっているかを確認する場合に有用です。
+</p>
+
+<pre>
+&#64;Override
+protected void onStart() {
+ super.onStart(); // Always call the superclass method first
+
+ // The activity is either being restarted or started for the first time
+ // so this is where we should make sure that GPS is enabled
+ LocationManager locationManager =
+ (LocationManager) getSystemService(Context.LOCATION_SERVICE);
+ boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
+
+ if (!gpsEnabled) {
+ // Create a dialog here that requests the user to enable GPS, and use an intent
+ // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action
+ // to take the user to the Settings screen to enable GPS when they click "OK"
+ }
+}
+
+&#64;Override
+protected void onRestart() {
+ super.onRestart(); // Always call the superclass method first
+
+ // Activity being restarted from stopped state
+}
+</pre>
+
+
+
+
+<p>システムがアクティビティを破棄する場合は、{@link android.app.Activity} に対して {@link android.app.Activity#onDestroy()} メソッドが呼び出されます。
+通常、{@link android.app.Activity#onStop()} を使用してリソースのほとんどを解放している可能性があるため、{@link
+android.app.Activity#onDestroy()} の呼び出しを受信する時点では、大抵のアプリでは必要な作業は少なくなっています。
+このメソッドは、メモリ リークにつながる可能性を持つリソースを一掃する最後のチャンスであるため、付加的なスレッドが破棄され、さらにメソッドのトレースのような長時間実行するその他のアクションも停止するようにする必要があります。
+
+
+</p>
+
diff --git a/docs/html-intl/intl/ja/training/basics/data-storage/databases.jd b/docs/html-intl/intl/ja/training/basics/data-storage/databases.jd
new file mode 100644
index 0000000..d0a4d8f
--- /dev/null
+++ b/docs/html-intl/intl/ja/training/basics/data-storage/databases.jd
@@ -0,0 +1,317 @@
+page.title=SQL データベースにデータを保存する
+page.tags=データ保存
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>このレッスンでの学習内容</h2>
+<ol>
+ <li><a href="#DefineContract">スキーマとコントラクトを定義する</a></li>
+ <li><a href="#DbHelper">SQL ヘルパーを使用してデータベースを作成する</a></li>
+ <li><a href="#WriteDbRow">データベースに情報を格納する</a></li>
+ <li><a href="#ReadDbRow">データベースから情報を読み取る</a></li>
+ <li><a href="#DeleteDbRow">データベースから情報を削除する</a></li>
+ <li><a href="#UpdateDbRow">データベースを更新する</a></li>
+</ol>
+
+<h2>関連ドキュメント</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#db">データベースを使用する</a></li>
+</ul>
+
+<!--
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/Sample.zip" class="button">Download the sample</a>
+ <p class="filename">Sample.zip</p>
+</div>
+-->
+
+</div>
+</div>
+
+
+<p>データベースへのデータ保存は、連絡先情報などの繰り返し使用する、または構造化されたデータに最適です。
+このクラスでは、受講者が全般的な SQL データベースの知識に精通していることを前提としており、Android 上での SQLite データベースの導入を支援します。
+
+Android 上でのデータベース使用の際に必要な API は、{@link android.database.sqlite} パッケージに含まれています。
+</p>
+
+
+<h2 id="DefineContract">スキーマとコントラクトを定義する</h2>
+
+<p>SQL データベースの重要な要素の 1 つがスキーマであり、これはデータベースの編成方法に関する正式な宣言です。
+スキーマは、データベースを作成するために使用する SQL 文に反映されます。
+<em>コントラクト</em> クラスとして知られているコンパニオン クラスの作成が有用です。コンパニオン クラスでは、スキーマのレイアウトを明示的に、そして体系的な自己文書化する方法で指定します。
+
+</p>
+
+<p>コントラクト クラスは、URI、表、列の名前を定義する定数のコンテナです。
+コントラクト クラスを使用すると、同じパッケージ内の他のすべてのクラスで、同じ定数を使用することができます。
+これにより、1 つの場所で列名を変更した場合に、それをコード全体にプロパゲートすることができます。
+</p>
+
+<p>コントラクト クラスを編成するお勧めの方法の 1 つは、クラスのルート レベルでデータベース全体に対しグローバルな定義を設定することです。
+その後、その列を列挙する各表の内部クラスを作成します。
+</p>
+
+<p class="note"><strong>注:</strong> {@link
+android.provider.BaseColumns} インターフェースを実装することで、内部クラスでは、カーソル アダプタのようないくつかの Android クラスでも存在を想定されている、
+{@code _ID} と呼ばれるプライマリキーフィールドを継承することができます。
+これは必須ではありませんが、データベースが Android フレームワークと調和して動作する上で役立ちます。
+</p>
+
+<p>たとえば、次のスニペットでは、単一の表の表名と列名を定義します。
+</p>
+
+
+<pre>
+public final class FeedReaderContract {
+ // To prevent someone from accidentally instantiating the contract class,
+ // give it an empty constructor.
+ public FeedReaderContract() {}
+
+ /* Inner class that defines the table contents */
+ public static abstract class FeedEntry implements BaseColumns {
+ public static final String TABLE_NAME = &quot;entry&quot;;
+ public static final String COLUMN_NAME_ENTRY_ID = &quot;entryid&quot;;
+ public static final String COLUMN_NAME_TITLE = &quot;title&quot;;
+ public static final String COLUMN_NAME_SUBTITLE = &quot;subtitle&quot;;
+ ...
+ }
+}
+</pre>
+
+
+
+<h2 id="DbHelper">SQL ヘルパーを使用してデータベースを作成する</h2>
+
+<p>データベースの概要を定義した後、データベースと表を作成、管理するメソッドを実装する必要があります。
+表を作成して削除するための一般的な宣言の例を次にいくつか示します。
+</P>
+
+<pre>
+private static final String TEXT_TYPE = &quot; TEXT&quot;;
+private static final String COMMA_SEP = &quot;,&quot;;
+private static final String SQL_CREATE_ENTRIES =
+ &quot;CREATE TABLE &quot; + FeedEntry.TABLE_NAME + &quot; (&quot; +
+ FeedEntry._ID + &quot; INTEGER PRIMARY KEY,&quot; +
+ FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP +
+ FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
+ ... // Any other options for the CREATE command
+ &quot; )&quot;;
+
+private static final String SQL_DELETE_ENTRIES =
+ &quot;DROP TABLE IF EXISTS &quot; + FeedEntry.TABLE_NAME;
+</pre>
+
+<p>デバイスの<a href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">内部ストレージ</a>にファイルを保存する場合と同様に、Android はアプリケーションに関連付けられているプライベート ディスク スペースにデータベースを格納します。
+
+デフォルトでは、この領域は他のアプリケーションからアクセスできないため、データの安全性は確保されています。
+</p>
+
+<p>一連の便利な API が、{@link
+android.database.sqlite.SQLiteOpenHelper}クラスで利用できます。このクラスを使用してデータベースへの参照を取得すると、<em>アプリケーションの起動時にではなく</em>必要な場合にのみ、データベースの作成、更新などの時間がかかる可能性が高い操作が実行されます。
+
+
+
+
+{@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase} または
+{@link android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} の呼び出し以外は必要ありません。</p>
+
+<p class="note"><strong>注:</strong> 長時間実行する可能性があるため、
+{@link android.os.AsyncTask} または {@link android.app.IntentService} などを使用して、{@link
+android.database.sqlite.SQLiteOpenHelper#getWritableDatabase} または {@link
+android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} をバックグラウンド スレッドで呼び出すようにしてください。
+</p>
+
+<p>{@link android.database.sqlite.SQLiteOpenHelper} を使用するには、
+{@link
+android.database.sqlite.SQLiteOpenHelper#onCreate onCreate()}、{@link
+android.database.sqlite.SQLiteOpenHelper#onUpgrade onUpgrade()}、{@link
+android.database.sqlite.SQLiteOpenHelper#onOpen onOpen()} コールバック メソッドを上書きするサブクラスを作成します。また
+{@link android.database.sqlite.SQLiteOpenHelper#onDowngrade onDowngrade()} を実装することもできますが、必須ではありません。
+</p>
+
+<p>次に、上記に示したいくつかのコマンドを使用した {@link
+android.database.sqlite.SQLiteOpenHelper} の実装例を示します。</p>
+
+<pre>
+public class FeedReaderDbHelper extends SQLiteOpenHelper {
+ // If you change the database schema, you must increment the database version.
+ public static final int DATABASE_VERSION = 1;
+ public static final String DATABASE_NAME = &quot;FeedReader.db&quot;;
+
+ public FeedReaderDbHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL(SQL_CREATE_ENTRIES);
+ }
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // This database is only a cache for online data, so its upgrade policy is
+ // to simply to discard the data and start over
+ db.execSQL(SQL_DELETE_ENTRIES);
+ onCreate(db);
+ }
+ public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ onUpgrade(db, oldVersion, newVersion);
+ }
+}
+</pre>
+
+<p>データベースにアクセスするには、{@link
+android.database.sqlite.SQLiteOpenHelper} のサブクラスのインスタンスを作成します。</p>
+
+<pre>
+FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());
+</pre>
+
+
+
+
+<h2 id="WriteDbRow">データベースに情報を格納する</h2>
+
+<p>{@link android.content.ContentValues}オブジェクトを {@link android.database.sqlite.SQLiteDatabase#insert insert()} メソッドに渡してデータベースにデータを格納できます。
+</p>
+
+<pre>
+// Gets the data repository in write mode
+SQLiteDatabase db = mDbHelper.getWritableDatabase();
+
+// Create a new map of values, where column names are the keys
+ContentValues values = new ContentValues();
+values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id);
+values.put(FeedEntry.COLUMN_NAME_TITLE, title);
+values.put(FeedEntry.COLUMN_NAME_CONTENT, content);
+
+// Insert the new row, returning the primary key value of the new row
+long newRowId;
+newRowId = db.insert(
+ FeedEntry.TABLE_NAME,
+ FeedEntry.COLUMN_NAME_NULLABLE,
+ values);
+</pre>
+
+<p>{@link android.database.sqlite.SQLiteDatabase#insert insert()}の最初の引数は単なる表の名前です。
+2 番目の引数は列の名前を指定します。この列では、{@link android.content.ContentValues} が空の場合にフレームワークが NULL を挿入できます(これを {@code "null"} に設定した場合、フレームワークは値がない場合には行を挿入しません)。
+
+
+</p>
+
+
+
+
+<h2 id="ReadDbRow">データベースから情報を読み取る</h2>
+
+<p>データベースから情報を読み取るには、{@link android.database.sqlite.SQLiteDatabase#query query()}メソッドを使用して選択条件および対象となる列をこれに渡します。このメソッドは、{@link android.database.sqlite.SQLiteDatabase#insert insert()}と {@link android.database.sqlite.SQLiteDatabase#update update()} 要素を組み合わせたもので(列リストを除く)、挿入するデータではなく取得対象のデータを定義します。
+
+
+
+クエリの結果は、
+{@link android.database.Cursor} オブジェクトとして返されます。</p>
+
+<pre>
+SQLiteDatabase db = mDbHelper.getReadableDatabase();
+
+// Define a <em>projection</em> that specifies which columns from the database
+// you will actually use after this query.
+String[] projection = {
+ FeedEntry._ID,
+ FeedEntry.COLUMN_NAME_TITLE,
+ FeedEntry.COLUMN_NAME_UPDATED,
+ ...
+ };
+
+// How you want the results sorted in the resulting Cursor
+String sortOrder =
+ FeedEntry.COLUMN_NAME_UPDATED + " DESC";
+
+Cursor c = db.query(
+ FeedEntry.TABLE_NAME, // The table to query
+ projection, // The columns to return
+ selection, // The columns for the WHERE clause
+ selectionArgs, // The values for the WHERE clause
+ null, // don't group the rows
+ null, // don't filter by row groups
+ sortOrder // The sort order
+ );
+</pre>
+
+<p>Cursor 内の特定の行に注目するには、いずれかの {@link android.database.Cursor} 移動メソッドを使用します。これは、必ず値の読み取りを開始する前に呼び出す必要があります。
+通常、初めに
+{@link android.database.Cursor#moveToFirst} を呼び出します。これは、結果の最初のエントリ上に「読み取り位置」を置きます。
+各行では、{@link android.database.Cursor#getString
+getString()} または {@link android.database.Cursor#getLong getLong()} のような
+{@link android.database.Cursor} 取得メソッドのいずれかを呼び出すことによって、列の値を読み取ることができます。各取得メソッドに対して、必要な列のインデックス位置を渡す必要があります。これは、{@link android.database.Cursor#getColumnIndex getColumnIndex()} または
+{@link android.database.Cursor#getColumnIndexOrThrow getColumnIndexOrThrow()}を呼び出すことによって取得できます。以下に例を示します。
+
+
+</p>
+
+<pre>
+cursor.moveToFirst();
+long itemId = cursor.getLong(
+ cursor.getColumnIndexOrThrow(FeedEntry._ID)
+);
+</pre>
+
+
+
+
+<h2 id="DeleteDbRow">データベースから情報を削除する</h2>
+
+<p>表から行を削除するには、削除対象の行を特定するための条件を指定する必要があります。
+データベース API により、SQL インジェクションから保護される選択条件を作成するメカニズムが提供されます。
+このメカニズムでは、選択の指定を選択句と選択引数に分割します。
+句では参照対象の列を定義し、また、列のテストを組み合わせることができます。
+
+引数はテスト対象の値であり、句にバインドされます。結果は通常の SQL 文と同様には扱われないため、SQL インジェクションの影響を受けません。
+
+</p>
+
+<pre>
+// Define 'where' part of query.
+String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + &quot; LIKE ?&quot;;
+// Specify arguments in placeholder order.
+String[] selectionArgs = { String.valueOf(rowId) };
+// Issue SQL statement.
+db.delete(table_name, selection, selectionArgs);
+</pre>
+
+
+
+<h2 id="UpdateDbRow">データベースを更新する</h2>
+
+<p>データベースの値のサブセットを変更する必要がある場合には、{@link
+android.database.sqlite.SQLiteDatabase#update update()} メソッドを使用します。</p>
+
+<p>表の更新では、{@link
+android.database.sqlite.SQLiteDatabase#insert insert()} のコンテンツ値の構文と、
+{@link android.database.sqlite.SQLiteDatabase#delete delete()} の {@code where} 構文が組み合わされます。</p>
+
+<pre>
+SQLiteDatabase db = mDbHelper.getReadableDatabase();
+
+// New value for one column
+ContentValues values = new ContentValues();
+values.put(FeedEntry.COLUMN_NAME_TITLE, title);
+
+// Which row to update, based on the ID
+String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + &quot; LIKE ?&quot;;
+String[] selectionArgs = { String.valueOf(rowId) };
+
+int count = db.update(
+ FeedReaderDbHelper.FeedEntry.TABLE_NAME,
+ values,
+ selection,
+ selectionArgs);
+</pre>
+
diff --git a/docs/html-intl/intl/ja/training/basics/data-storage/files.jd b/docs/html-intl/intl/ja/training/basics/data-storage/files.jd
new file mode 100644
index 0000000..dddfe37
--- /dev/null
+++ b/docs/html-intl/intl/ja/training/basics/data-storage/files.jd
@@ -0,0 +1,379 @@
+page.title=ファイルを保存する
+page.tags=データ ストレージ
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>このレッスンでの学習内容</h2>
+<ol>
+ <li><a href="#InternalVsExternalStorage">内部または外部ストレージを選択する</a></li>
+ <li><a href="#GetWritePermission">外部ストレージのパーミッションを取得する</a></li>
+ <li><a href="#WriteInternalStorage">内部ストレージ上にファイルを保存する</a></li>
+ <li><a href="#WriteExternalStorage">外部ストレージ上にファイルを保存する</a></li>
+ <li><a href="#GetFreeSpace">空き領域をクエリする</a></li>
+ <li><a href="#DeleteFile">ファイルを削除する</a></li>
+</ol>
+
+<h2>関連ドキュメント</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">内部ストレージを使用する</a>
+</li>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#filesExternal">外部ストレージを使用する</a>
+</li>
+</ul>
+
+</div>
+</div>
+
+<p>Android は、他のプラットフォーム上のディスクベースの
+ファイル システムと同様なファイルシステムを使用しています。このレッスンでは、
+{@link java.io.File} API を使用したファイルの読み書きに関する Android ファイルシステムの操作方法について説明します。
+</p>
+
+<p>{@link java.io.File} オブジェクトは、スキップすることなく開始から終了までの順序で大量のデータを読み取りまたは書き込みするのに適しています。
+これは、たとえば画像ファイルやネットワークを介して交換される任意のファイルに対して有効です。
+</p>
+
+<p>このレッスンでは、自分のアプリで基本的なファイル関連のタスクを実行する方法を紹介します。ここでは、Linux ファイルシステムの基礎と
+{@link java.io} での標準的なファイル入力/出力の API に精通していることを前提としています。
+</p>
+
+
+<h2 id="InternalVsExternalStorage">内部または外部ストレージを選択する</h2>
+
+<p>すべての Android 端末には、「内部」ストレージと「外部」ストレージの 2 つのファイル記憶領域があります。これらの名前は初期の Android の名残として、当時ほとんどの端末が内蔵の不揮発性メモリ(内部ストレージ)を備えていたのに加え、マイクロ SD カードのような取り外し可能な記憶媒体(外部記憶装置)も備えていたことから来ています。一部の端末では、永続的なストレージ領域を「内部」と「外部」のパーティションに分割しており、リムーバブル記憶媒体が備わっていない場合でも常に 2 つのストレージ スペースがあり、外部ストレージが取り外し可能であるか否かにかかわらず、API の動作は同じです。以下のリストでは、各ストレージ スペースの特徴を要約しています。
+
+
+
+
+
+</p>
+
+<div class="col-5" style="margin-left:0">
+<p><b>内部ストレージ:</b></p>
+<ul>
+<li>常に使用可能。</li>
+<li>ここに保存されたファイルは、デフォルトでは自分のアプリからのみアクセスできます。</li>
+<li>ユーザーがアプリをアンインストールすると、システムは内部ストレージから当該アプリのファイルをすべて削除します。
+</li>
+</ul>
+<p>ユーザーからも他のアプリからも、自分のファイルにアクセスできないようにしたい場合、内部ストレージが最適です。
+</p>
+</div>
+
+<div class="col-7" style="margin-right:0">
+<p><b>外部ストレージ:</b></p>
+<ul>
+<li>ユーザーは、USB ストレージなどの外部記憶装置をマウントできますが、端末から取り外す場合もあるため、常に使用可能というわけではありません。
+</li>
+<li>誰でも読み取り可能なため、ここに保存されたファイルは自分のコントロールの及ばない所で読み取られる可能性があります。
+</li>
+<li>ユーザーがアプリをアンインストールすると、当該アプリのファイルは、{@link android.content.Context#getExternalFilesDir
+getExternalFilesDir()} からディレクトリに保存された場合に限り、ここからすべて削除されます。
+</li>
+</ul>
+<p>アクセス制限を必要としないファイルや、他のアプリと共有したり、ユーザーがコンピュータ経由でアクセスできるようにしたりするファイルの場合、外部ストレージが最適です。
+
+</p>
+</div>
+
+
+<p class="note" style="clear:both">
+<strong>ヒント: </strong>アプリはデフォルトでは内部ストレージにインストールされますが、自分のアプリが外部ストレージにインストールされるように、マニフェスト内で <a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code
+android:installLocation}</a> 属性を指定できます。
+
+APK のサイズが非常に大きく、内部ストレージよりも外部ストレージ容量が大きい場合、ユーザーにとってこのオプションは便利なものとなります。
+詳細については、<a href="{@docRoot}guide/topics/data/install-location.html">App Install Location</a> をご覧ください。
+</p>
+
+
+<h2 id="GetWritePermission">外部ストレージのパーミッションを取得する</h2>
+
+<p>外部ストレージに書き込むには、自分の<a href="{@docRoot}guide/topics/manifest/manifest-intro.html">マニフェスト ファイル</a>で
+{@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} パーミッションをリクエストする必要があります。</p>
+
+<pre>
+&lt;manifest ...>
+ &lt;uses-permission android:name=&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot; /&gt;
+ ...
+&lt;/manifest>
+</pre>
+
+<div class="caution"><p><strong>警告: </strong>現在、すべてのアプリは特別なパーミッションを必要とせずに、外部ストレージからの読み取りが可能です。
+
+ただし、これは将来のリリースで変更される予定です。自分のアプリで外部ストレージの読み取り(書き込みではなく)の必要がある場合は、{@link
+android.Manifest.permission#READ_EXTERNAL_STORAGE} パーミッションを宣言する必要があります。
+アプリが正常に動作し続けるようにするには、すぐにこのパーミッションを宣言して、変更を有効にする必要があります。
+</p>
+<pre>
+&lt;manifest ...>
+ &lt;uses-permission android:name=&quot;android.permission.READ_EXTERNAL_STORAGE&quot; /&gt;
+ ...
+&lt;/manifest>
+</pre>
+<p>ただし、自分のアプリで {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}パーミッションを使用している場合は、暗黙的に外部ストレージの読み取りパーミッションも持つことになります。
+</p>
+</div>
+
+<p>内部ストレージにファイルを保存する際には、一切のパーミッションを必要としません。
+自分のアプリは常に、内部ストレージ ディレクトリ内のファイルの読み取りおよび書き込みパーミッションを持っています。
+</p>
+
+
+
+
+
+<h2 id="WriteInternalStorage">内部ストレージ上にファイルを保存する</h2>
+
+<p>内部ストレージにファイルを保存する場合は、次の 2 つのメソッドのいずれかを呼び出すことにより、
+{@link java.io.File} として適切なディレクトリを取得することができます。</p>
+
+<dl>
+ <dt>{@link android.content.Context#getFilesDir}</dt>
+ <dd>自分のアプリ用の内部ディレクトリを示す {@link java.io.File} を返します。</dd>
+ <dt>{@link android.content.Context#getCacheDir}</dt>
+ <dd>自分のアプリの一時キャッシュ ファイル用の内部ディレクトリを示す {@link java.io.File} を返します。
+必要がなくなった各ファイルを削除して、1MB などの、任意の時点で使用するメモリ量として適度なサイズ制限を実装してください。
+
+システムはストレージが不足し始めた場合、警告なしでキャッシュ ファイルを削除することがあります。
+</dd>
+</dl>
+
+<p>これらのディレクトリのいずれかに新しいファイルを作成するには、自分の内部ストレージ ディレクトリを指定する、上記のいずれかのメソッドで提供された {@link java.io.File} を渡して、{@link
+java.io.File#File(File,String) File()} コンストラクタを使用することができます。
+次に例を示します。</p>
+
+<pre>
+File file = new File(context.getFilesDir(), filename);
+</pre>
+
+<p>代わりに {@link
+android.content.Context#openFileOutput openFileOutput()} を呼び出して、自分の内部ディレクトリ内のファイルに書き込みを行う {@link java.io.FileOutputStream}を取得することができます。
+ファイルにテキストを書き込む方法の例を次に示します。
+</p>
+
+<pre>
+String filename = "myfile";
+String string = "Hello world!";
+FileOutputStream outputStream;
+
+try {
+ outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
+ outputStream.write(string.getBytes());
+ outputStream.close();
+} catch (Exception e) {
+ e.printStackTrace();
+}
+</pre>
+
+<p>または、いくつかのファイルをキャッシュする必要がある場合は、代わりに {@link
+java.io.File#createTempFile createTempFile()} を使用してください。たとえば、次のメソッドでは {@link java.net.URL} からファイル名を抽出し、自分のアプリの内部キャッシュ ディレクトリに、抽出した名前でファイルを作成します。
+
+</p>
+
+<pre>
+public File getTempFile(Context context, String url) {
+ File file;
+ try {
+ String fileName = Uri.parse(url).getLastPathSegment();
+ file = File.createTempFile(fileName, null, context.getCacheDir());
+ catch (IOException e) {
+ // Error while creating file
+ }
+ return file;
+}
+</pre>
+
+<p class="note"><strong>注:</strong>アプリの内部ストレージ ディレクトリは、Android ファイルシステムの特定の場所にアプリのパッケージ名で指定されています。技術的には、読み取り可能になるようファイル モードを設定した場合、別のアプリから自分の内部ストレージのファイルを読むことができます。
+
+
+
+ただし、他のアプリ側でもアプリのパッケージ名とファイル名が既知である必要があります。
+他のアプリからは、自分のアプリの内部ディレクトリを参照することはできず、明示的にファイルを読み取り可能または書き込み可能に設定しない限り、読み書きのアクセス権もないからです。
+すなわち、内部ストレージ上のファイルに対して {@link android.content.Context#MODE_PRIVATE} を使用する限り、ファイルは他のアプリからアクセス可能になることはありません。
+
+</p>
+
+
+
+
+
+<h2 id="WriteExternalStorage">外部ストレージ上にファイルを保存する</h2>
+
+<p>外部ストレージは使用できない場合があります(ユーザーが PC にストレージをマウントしているか、外部ストレージを提供する SD カードを取り外した場合など)。アクセスする前に、当該ボリュームが利用可能であるかを常に確認する必要があります。
+
+{@link android.os.Environment#getExternalStorageState} を呼び出すことによって、外部ストレージの状態をクエリすることができます。
+返された状態が {@link android.os.Environment#MEDIA_MOUNTED} に等しい場合は、ファイルの読み取りと書き込みができます。
+
+たとえば、次のメソッドは、ストレージの可用性を判断するのに有用です。
+</p>
+
+<pre>
+/* Checks if external storage is available for read and write */
+public boolean isExternalStorageWritable() {
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+ return false;
+}
+
+/* Checks if external storage is available to at least read */
+public boolean isExternalStorageReadable() {
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
+ }
+ return false;
+}
+</pre>
+
+<p>外部ストレージは、ユーザーや他のアプリから変更可能ですが、ここで保存可能なファイルには次の 2 つのカテゴリがあります。
+</p>
+
+<dl>
+ <dt>パブリック ファイル</dt>
+ <dd>他のアプリおよびユーザーから自由に利用可能にすべきファイル。
+ユーザーがアプリをアンインストールしても、これらのファイルはユーザーから利用可能なままにしておく必要があります。
+
+ <p>たとえば、アプリで撮影した写真、その他のダウンロードされたファイルなどです。</p>
+ </dd>
+ <dt>プライベート ファイル</dt>
+ <dd>正当に自分のアプリに帰属しているファイルは、ユーザーがアプリをアンインストールした時点で削除する必要があります。これらのファイルは外部ストレージ上にあるため、技術的にはユーザーと他のアプリからアクセス可能ですが、現実問題としてアプリを離れたユーザーにとって価値を持たないファイルです。そのため、ユーザーがアプリをアンインストールすると、アプリの外部プライベート ディレクトリ内のすべてのファイルが削除されます。
+
+
+
+
+ <p>たとえば、自分のアプリでダウンロードした追加のリソースや一時的なメディア ファイルです。</p>
+ </dd>
+</dl>
+
+<p>外部ストレージにパブリック ファイルを保存する場合は、
+{@link android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()} メソッドを使用して、外部ストレージ上の適切なディレクトリを示す {@link java.io.File} を取得します。
+このメソッドは、{@link android.os.Environment#DIRECTORY_MUSIC} または {@link
+android.os.Environment#DIRECTORY_PICTURES} などの保存するファイルの種類を指定する引数を取り、他のパブリック ファイルとともに論理的に整理することができます。
+
+次に例を示します。</p>
+
+<pre>
+public File getAlbumStorageDir(String albumName) {
+ // Get the directory for the user's public pictures directory.
+ File file = new File(Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES), albumName);
+ if (!file.mkdirs()) {
+ Log.e(LOG_TAG, "Directory not created");
+ }
+ return file;
+}
+</pre>
+
+
+<p>自分のアプリのプライベート ファイルを保存する場合は、{@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()} を呼び出して希望するディレクトリのタイプを示す名前を渡し、適切なディレクトリを取得することができます。
+
+このように作成した各ディレクトリは、ユーザーがアプリをアンインストールするときにシステムが削除するアプリの外部ストレージ ファイルのすべてをカプセル化する親ディレクトリに追加されます。
+
+</p>
+
+<p>ここでは、個々のフォト アルバム用のディレクトリを作成するために使用できるメソッドの例を次に示します。</p>
+
+<pre>
+public File getAlbumStorageDir(Context context, String albumName) {
+ // Get the directory for the app's private pictures directory.
+ File file = new File(context.getExternalFilesDir(
+ Environment.DIRECTORY_PICTURES), albumName);
+ if (!file.mkdirs()) {
+ Log.e(LOG_TAG, "Directory not created");
+ }
+ return file;
+}
+</pre>
+
+<p>あらかじめ定義されたサブディレクトリ名のいずれもが自分のファイルに適合しない場合、代わりに {@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()} を呼び出し、{@code null} を渡すことができます。これにより、外部ストレージ上のアプリのプライベート ディレクトリのルート ディレクトリが返されます。
+</p>
+
+<p>{@link android.content.Context#getExternalFilesDir getExternalFilesDir()}は、ユーザーがアプリをアンインストールすると削除されるディレクトリ内にディレクトリを作成することに注意してください。ユーザーがアプリをアンインストールした後も、保存対象のファイルを利用可能にすべき場合(自分のアプリがカメラであり、ユーザーが撮った写真の利用を望むような場合)は、代わりに {@link android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()} を使用する必要があります。
+
+
+
+</p>
+
+
+<p>共有ファイルに対して {@link android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()} を使用しているか、自分のアプリにとってプライベートなファイルに対して
+{@link android.content.Context#getExternalFilesDir
+getExternalFilesDir()} を使用しているかどうかに関係なく、
+{@link android.os.Environment#DIRECTORY_PICTURES} のような API 定数が提供するディレクトリ名を使用することが重要です。
+
+これらのディレクトリ名により、ファイルがシステムによって正しく処理されるようになります。
+たとえば、{@link
+android.os.Environment#DIRECTORY_RINGTONES} に保存されたファイルは、システムのメディア スキャナにより音楽ではなく着信音として分類されます。
+</p>
+
+
+
+
+<h2 id="GetFreeSpace">空き領域をクエリする</h2>
+
+<p>前もって保存対象のデータ量がわかっている場合は、{@link java.io.File#getFreeSpace} または {@link
+java.io.File#getTotalSpace} 呼び出して、{@link
+java.io.IOException} を生じさせることなく十分な空き領域が利用可能かどうかを調べることができます。
+これらのメソッドでは、それぞれ、ストレージ ボリューム内の現在利用可能な領域と総領域がそれぞれ得られます。
+この情報は、一定の閾値以上のストレージ ボリュームの消費を避けるためにも有用です。
+</p>
+
+<p>しかし、システム上、{@link java.io.File#getFreeSpace} で示されたバイト数の書き込みは保証されるものではありません。
+返された数量が保存するデータのサイズよりも数 MB 上回る場合、またはファイルシステムの使用率が 90%未満の場合は、続行しても安全でしょう。それ以外の場合は、ストレージへの書き込みは避けるべきです。
+
+
+</p>
+
+<p class="note"><strong>注:</strong> ファイルを保存する前に、使用可能な領域の量をチェックする必要はありません。
+代わりにすぐにファイルを書き込んでみて、不都合が生じた場合に {@link java.io.IOException} を受け取ることができます。
+正確にどのくらいの領域が必要か不明な場合は、これを行う必要がある場合があります。
+たとえばファイルを保存する前に、PNG 画像を JPEG に 変換してエンコーディングを変更した場合、事前にファイルのサイズを知ることができません。
+
+</p>
+
+
+
+
+<h2 id="DeleteFile">ファイルを削除する</h2>
+
+<p>不要になったファイルは、常に削除する必要があります。ファイルを削除する最も簡単な方法は、
+開かれたファイル上で参照呼び出し {@link java.io.File#delete} を行うことです。</p>
+
+<pre>
+myFile.delete();
+</pre>
+
+<p>ファイルが内部ストレージに保存されている場合は、{@link android.content.Context} を使用して場所を特定し、
+{@link android.content.Context#deleteFile deleteFile()} を呼び出してファイルを削除することもできます。</p>
+
+<pre>
+myContext.deleteFile(fileName);
+</pre>
+
+<div class="note">
+<p><strong>注:</strong> ユーザーがアプリをアンインストールすると、Android システムは次を削除します。
+</p>
+<ul>
+<li>内部ストレージに保存したすべてのファイル</li>
+<li>{@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()} を使用して外部ストレージに保存したすべてのファイル</li>
+</ul>
+<p>ただし、定期的に
+{@link android.content.Context#getCacheDir()} で作成されたすべてのキャッシュ済みファイルを手動で削除し、必要なくなったファイルも定期的に削除する必要があります。
+</p>
+</div>
+
diff --git a/docs/html-intl/intl/ja/training/basics/data-storage/index.jd b/docs/html-intl/intl/ja/training/basics/data-storage/index.jd
new file mode 100644
index 0000000..9109143
--- /dev/null
+++ b/docs/html-intl/intl/ja/training/basics/data-storage/index.jd
@@ -0,0 +1,57 @@
+page.title=データの保存
+page.tags=データ ストレージ、ファイル、SQL、データベース、環境設定
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>必要な知識と前提条件</h2>
+<ul>
+ <li>Android 1.6(API レベル 4)以降</li>
+ <li>Map のキー値コレクションに精通していること</li>
+ <li>Java ファイルの I/O API に精通していること</li>
+ <li>SQL データベースに精通していること</li>
+</ul>
+
+<h2>関連ドキュメント</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html">ストレージ オプション</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>ほとんどの Android アプリは、ユーザー操作の進行状況が失われないように {@link android.app.Activity#onPause onPause()} 中のアプリの状態に関する情報を保存する目的のみの場合でも、データを保存する必要があります。
+多くの主要アプリではユーザー設定も保存する必要があり、一部のアプリでは、ファイルやデータベース内の大量の情報を管理する必要があります。
+
+このクラスでは、次のような Android の主要なデータ ストレージ オプションを紹介します。
+</p>
+
+<ul>
+ <li>単純なデータ タイプのキー値のペアを共有の環境設定ファイル内に保存する
+</li>
+ <li>Android のファイル システム内に任意のファイルを保存する</li>
+ <li>SQLite で管理されたデータベースを使用する</li>
+</ul>
+
+
+<h2>レッスン</h2>
+
+<dl>
+ <dt><b><a href="shared-preferences.html">キー値セットを保存する</a></b></dt>
+ <dd>キー値ペアの少量の情報を格納するための、共有環境設定ファイルの使用について学びます。
+</dd>
+
+ <dt><b><a href="files.html">ファイルを保存する</a></b></dt>
+ <dd>通常順に読み取られる長いデータ シーケンスの格納方法など、基本的なファイルの保存について学びます。
+</dd>
+
+ <dt><b><a href="databases.html">SQL データベースにデータを保存する</a></b></dt>
+ <dd>構造化データを読み書きする際の SQLite データベースの使用について学びます。</dd>
+
+</dl>
diff --git a/docs/html-intl/intl/ja/training/basics/data-storage/shared-preferences.jd b/docs/html-intl/intl/ja/training/basics/data-storage/shared-preferences.jd
new file mode 100644
index 0000000..5f6d5ff
--- /dev/null
+++ b/docs/html-intl/intl/ja/training/basics/data-storage/shared-preferences.jd
@@ -0,0 +1,120 @@
+page.title=キー値セットを保存する
+page.tags=データ ストレージ
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>このレッスンでの学習内容</h2>
+<ol>
+ <li><a href="#GetSharedPreferences">SharedPreferences を操作する</a></li>
+ <li><a href="#WriteSharedPreference">共有の環境設定に書き込む</a></li>
+ <li><a href="#ReadSharedPreference">共有の環境設定から読み取る</a></li>
+</ol>
+
+<h2>関連ドキュメント</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#pref">共有の環境設定を使用する</a></li>
+</ul>
+
+</div>
+</div>
+
+
+<p>保存しようとするキー値の比較的小さなコレクションがある場合は、
+{@link android.content.SharedPreferences} API を使用する必要があります。
+{@link android.content.SharedPreferences} オブジェクトは、キー値のペアを含むファイルをポイントし、読み取りと書き込み用の単純なメソッドを提供します。
+各
+{@link android.content.SharedPreferences} ファイルは、フレームワークによって管理され、プライベートまたは共有にすることができます。
+</p>
+
+<p>このクラスでは、{@link android.content.SharedPreferences} API を使用して単純な値を格納し、取得する方法について説明します。
+</p>
+
+<p class="note"><strong>注:</strong> {@link android.content.SharedPreferences} API は、キー値のペアの読み取りおよび書き込みの目的にのみ使用できます。自分のアプリの設定用のユーザー インタフェースのビルドを支援する
+ {@link android.preference.Preference} API と混同しないようにしてください(ただし、これらは
+ {@link android.content.SharedPreferences} を実装として使用してアプリの設定を保存します)。
+
+{@link
+android.preference.Preference} API の使用方法については、<a href="{@docRoot}guide/topics/ui/settings.html">設定</a>のガイドを参照してください。</p>
+
+<h2 id="GetSharedPreferences">SharedPreferences を操作する</h2>
+
+<p>新しい共有の環境設定ファイルを作成したり、次の 2 つのメソッドのいずれかを呼び出すことにより、既存のファイルにアクセスできます。
+</p>
+<ul>
+ <li>{@link android.content.Context#getSharedPreferences(String,int)
+getSharedPreferences()} - 最初のパラメータで指定した名前で識別される共有の環境設定ファイルが複数必要な場合に使用します。
+自分のアプリの任意の
+{@link android.content.Context} から、これを呼び出すことができます。</li>
+ <li>{@link android.app.Activity#getPreferences(int) getPreferences()} - アクティビティに対して共有の環境設定ファイルを 1 つのみ使用する必要がある場合、
+{@link android.app.Activity} からこれを使用します。
+これにより、アクティビティに属するデフォルトの共有の環境設定ファイルを取得できるので、名前を指定する必要はありません。
+</li>
+</ul>
+
+<p>たとえば、{@link android.app.Fragment} 内で次のコードが実行されます。これにより、リソース文字列 {@code R.string.preference_file_key} で識別する共有の環境設定ファイルにアクセスし、自分のアプリからのみアクセス可能になるよう、プライベート モードを使用して開きます。
+
+
+</p>
+
+<pre>
+Context context = getActivity();
+SharedPreferences sharedPref = context.getSharedPreferences(
+ getString(R.string.preference_file_key), Context.MODE_PRIVATE);
+</pre>
+
+<p>共有の環境設定ファイルに名前を付ける場合は、{@code "com.example.myapp.PREFERENCE_FILE_KEY"} のような、自分のアプリを識別できる、一意の名前を使用する必要があります。
+</p>
+
+<p>または、アクティビティ用に共有の環境設定ファイルが 1 つのみ必要な場合、
+{@link android.app.Activity#getPreferences(int) getPreferences()} メソッドを使用することができます。</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+</pre>
+
+<p class="caution"><strong>警告: </strong>{@link android.content.Context#MODE_WORLD_READABLE} または {@link
+android.content.Context#MODE_WORLD_WRITEABLE} を使用して共有の環境設定を作成した場合、ファイル識別子が既知である任意の他のアプリが自分のデータにアクセスできるようになります。
+
+</p>
+
+
+<h2 id="WriteSharedPreference">共有の環境設定に書き込む</h2>
+
+<p>共有の環境設定ファイルに書き込むには、自分の {@link android.content.SharedPreferences} で {@link
+android.content.SharedPreferences#edit} を呼び出して、{@link
+android.content.SharedPreferences.Editor} を作成します。</p>
+
+<p>{@link
+android.content.SharedPreferences.Editor#putInt putInt()} や {@link
+android.content.SharedPreferences.Editor#putString putString()} などのメソッドを使用して、書き込む対象のキーと値を渡します。{@link
+android.content.SharedPreferences.Editor#commit} を呼び出して変更を保存します。次に例を示します。</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+SharedPreferences.Editor editor = sharedPref.edit();
+editor.putInt(getString(R.string.saved_high_score), newHighScore);
+editor.commit();
+</pre>
+
+
+<h2 id="ReadSharedPreference">共有の環境設定から読み取る</h2>
+
+<p>共有の環境設定ファイルから希望の値を取得するには、{@link
+android.content.SharedPreferences#getInt getInt()} や {@link
+android.content.SharedPreferences#getString getString()} などのメソッドを呼び出して値のキーを指定しますが、オプションで、キーが存在しない場合に戻すデフォルト値を指定します。
+
+次に例を示します。</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+int defaultValue = getResources().getInteger(R.string.saved_high_score_default);
+long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue);
+</pre>
+
diff --git a/docs/html-intl/intl/ja/training/basics/intents/filters.jd b/docs/html-intl/intl/ja/training/basics/intents/filters.jd
new file mode 100644
index 0000000..5f0d69a
--- /dev/null
+++ b/docs/html-intl/intl/ja/training/basics/intents/filters.jd
@@ -0,0 +1,236 @@
+page.title=他のアプリからのアクティビティの開始を許可する
+page.tags=インテント
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>このレッスンでの学習内容</h2>
+<ol>
+ <li><a href="#AddIntentFilter">インテント フィルタを追加する</a></li>
+ <li><a href="#HandleIntent">自分のアクティビティでインテントを処理する</a></li>
+ <li><a href="#ReturnResult">結果を返す</a></li>
+</ol>
+
+<h2>関連ドキュメント</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">単純なデータの共有</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">ファイルの共有</a>
+</ul>
+ </div>
+</div>
+
+<p>前 2 回のレッスンでは、自分のアプリから別のアプリのアクティビティを開始する場合について焦点を当てました。一方、自分のアプリで別のアプリにとって役に立つかもしれないアクションを実行できる場合について、自分のアプリが他のアプリからのアクション要求に応答できるようにする必要があります。
+
+たとえば、友人とメッセージや写真を共有できるソーシャル アプリをビルドした場合、ユーザーが別のアプリから「共有」アクションを開始し、こちら側のアプリを起動してそのアクションを実行できるよう、{@link android.content.Intent#ACTION_SEND} インテントをサポートすることが最善の方法です。
+
+
+</p>
+
+<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>アプリが端末にインストールされている場合、システムはインテント フィルタを識別し、インストールされているすべてのアプリでサポートされるインテントの内部カタログに情報を追加します。アプリが暗黙的インテントを使って {@link android.app.Activity#startActivity
+startActivity()} または {@link android.app.Activity#startActivityForResult startActivityForResult()}を呼び出すと、システムがどのアクティビティ(または複数のアクティビティ)がインテントに応答できるかを特定します。
+
+
+
+</p>
+
+
+
+<h2 id="AddIntentFilter">インテント フィルタを追加する</h2>
+
+<p>アクティビティがどのインテントを処理できるか適切に定義するためには、アクティビティが受け入れるアクションとデータのタイプについて、追加する各インテント フィルタをできるだけ具体的にする必要があります。
+
+</p>
+
+<p>アクティビティが {@link android.content.Intent} オブジェクトに関する次の基準を満たしているインテント フィルタを持つ場合、システムは、アクティビティに対して所定の {@link android.content.Intent} を送信することができます。
+</p>
+
+<dl>
+ <dt>アクション</dt>
+ <dd>実行するアクション名を表す文字列。通常、
+{@link android.content.Intent#ACTION_SEND} や {@link android.content.Intent#ACTION_VIEW} などのプラットフォームに定義された値のいずれか。
+ <p><a href="{@docRoot}guide/topics/manifest/action-element.html">{@code &lt;action&gt;}</a> 要素を使用してインテント フィルタでこれを指定します。この要素で指定した値は、API 定数ではなく、アクションの完全な文字列名(下記の例を参照)である必要があります。
+
+</p></dd>
+
+ <dt>データ</dt>
+ <dd>インテントに関連するデータの詳細。
+ <p><a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data&gt;}</a> 要素を使用して、インテント フィルタでこれを指定します。この要素で 1 つ以上の属性を
+使用して、MIME タイプのみ、URI 接頭辞のみ、URI スキームのみ、またはこれらと受け入れられるデータ タイプを示すその他の項目の組み合わせを指定することができます。
+
+</p>
+ <p class="note"><strong>注:</strong> {@link android.net.Uri} データに関する詳細を宣言する必要がない場合(アクティビティが URI ではなく他の種類の「特別」データを処理するときなど)は、
+{@code text/plain} {@code image/jpeg} のようなアクティビティが処理するデータのタイプを宣言する {@code android:mimeType} 属性のみを指定する必要があります。
+
+</p>
+</dd>
+ <dt>カテゴリ</dt>
+ <dd>インテントを処理するアクティビティを特徴づけるための追加的な方法を提供し、通常はユーザーの操作や起動元の場所に関連付けられます。
+システムでサポートされているいくつかの異なるカテゴリがありますが、大抵のカテゴリはほとんど使用されません。
+しかし、すべての暗黙的インテントは、デフォルトでは
+{@link android.content.Intent#CATEGORY_DEFAULT} を使用して定義されています。
+ <p><a href="{@docRoot}guide/topics/manifest/category-element.html">{@code &lt;category&gt;}</a>
+要素を使用して、インテント フィルタでこれを指定します。</p></dd>
+</dl>
+
+<p>インテント フィルタでは、それぞれの基準を<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter&gt;}</a> 要素内でネストした対応する XML 要素を使用して宣言することによって、アクティビティが受け入れる基準を宣言することができます。
+
+</p>
+
+<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;data android:mimeType="image/*"/>
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p>受信するインテントはそれぞれ 1 つのアクションと 1 つのデータ タイプのみを指定しますが、各
+<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a> 内で <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>、<a href="{@docRoot}guide/topics/manifest/data-element.html">{@code
+&lt;data&gt;}</a> 要素の複数のインスタンスを宣言することもできます。
+</p>
+
+<p>アクションとデータのいずれか 2 つのペアが、各自の動作において相互に排他的である場合は、別のインテント フィルタを作成して、どのデータ タイプと組み合わされたときにとのアクションが受け入れられるかを指定する必要があります。
+
+</p>
+
+<p>たとえば、アクティビティが {@link
+android.content.Intent#ACTION_SEND} と {@link
+android.content.Intent#ACTION_SENDTO} の両方のインテントに関してテキストと画像の両方を処理するとします。この場合は、次の 2 つのアクションのための 2 つの別々のインテント フィルタを定義する必要があります。なぜなら {@link
+android.content.Intent#ACTION_SENDTO} インテントは、URI スキームの {@code send} または {@code sendto} を使用して受信者のアドレスを指定するために、
+{@link android.net.Uri} データを使用する必要があるからです。
+次に例を示します。</p>
+
+<pre>
+&lt;activity android:name="ShareActivity">
+ &lt;!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.SENDTO"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:scheme="sms" />
+ &lt;data android:scheme="smsto" />
+ &lt;/intent-filter>
+ &lt;!-- filter for sending text or images; accepts SEND action and text or image data -->
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.SEND"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:mimeType="image/*"/>
+ &lt;data android:mimeType="text/plain"/>
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p class="note"><strong>注:</strong> 暗黙的インテントを受信するためには、インテント フィルタで
+{@link android.content.Intent#CATEGORY_DEFAULT} カテゴリを含める必要があります。{@link
+android.app.Activity#startActivity startActivity()} と {@link
+android.app.Activity#startActivityForResult startActivityForResult()} メソッドは、すべてのインテントを {@link android.content.Intent#CATEGORY_DEFAULT} カテゴリを宣言しているものとして処理します。
+インテント フィルタで宣言していない場合、暗黙的インテントはアクティビティに紐付けされません。
+</p>
+
+<p>ソーシャル共有行動を実行する {@link android.content.Intent#ACTION_SEND}インテントの送受信方法の詳細については、<a href="{@docRoot}training/sharing/receive.html">他のアプリから単純なデータを受信する</a> のレッスンを参照してください。
+</p>
+
+
+<h2 id="HandleIntent">自分のアクティビティでインテントを処理する</h2>
+
+<p>アクティビティで実行するアクションを決定するために、起動時に使用された {@link
+android.content.Intent} を読み取ることができます。</p>
+
+<p>アクティビティが開始されたら、{@link android.app.Activity#getIntent()} を呼び出して、アクティビティを開始した
+{@link android.content.Intent} を取得します。アクティビティのライフサイクル中はいつでもこれを行うことができますが、通常は、
+{@link android.app.Activity#onCreate onCreate()} や {@link android.app.Activity#onStart()} などの早い段階のコールバックの間に行う必要があります。
+</p>
+
+<p>次に例を示します。</p>
+
+<pre>
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.main);
+
+ // Get the intent that started this activity
+ Intent intent = getIntent();
+ Uri data = intent.getData();
+
+ // Figure out what to do based on the intent type
+ if (intent.getType().indexOf("image/") != -1) {
+ // Handle intents with image data ...
+ } else if (intent.getType().equals("text/plain")) {
+ // Handle intents with text ...
+ }
+}
+</pre>
+
+
+<h2 id="ReturnResult">結果を返す</h2>
+
+<p>呼び出し元のアクティビティに結果を返したい場合は、{@link
+android.app.Activity#setResult(int,Intent) setResult()} を呼び出して結果コードと結果の {@link
+android.content.Intent} を指定します。操作が実行され、ユーザーが元のアクティビティに復帰する必要がある場合、
+{@link android.app.Activity#finish()} を呼び出してアクティビティを閉じます(その後破棄します)。次に例を示します。
+</p>
+
+<pre>
+// Create intent to deliver some kind of result data
+Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");
+setResult(Activity.RESULT_OK, result);
+finish();
+</pre>
+
+<p>結果に対しては常に結果コードを指定する必要があります。通常は {@link
+android.app.Activity#RESULT_OK} または {@link android.app.Activity#RESULT_CANCELED} のいずれかになります。その後、必要に応じて {@link android.content.Intent} を使用して、追加のデータを指定することができます。
+</p>
+
+<p class="note"><strong>注:</strong> 結果は、デフォルトでは {@link
+android.app.Activity#RESULT_CANCELED} に設定されています。したがって、ユーザーがアクションを完了する前に<em>戻る</em>ボタンを押して、結果がまだ設定されていない場合、元のアクティビティは「キャンセルされた」結果を受け取ります。
+
+</p>
+
+<p>いくつかの結果オプションのいずれかを示す整数を返す必要がある場合は、0 よりも大きい任意の値に結果コードを設定することができます。
+結果コードを使用して整数を返す場合に {@link android.content.Intent} を含める必要がなければ、{@link
+android.app.Activity#setResult(int) setResult()} を呼び出して結果コードのみを渡すことができます。
+次に例を示します。</p>
+
+<pre>
+setResult(RESULT_COLOR_RED);
+finish();
+</pre>
+
+<p>この場合、可能性のある結果の数はわずかであるため、結果コードは、ローカルに定義されている整数(0 より大きい)になります。
+これは、自分が作成したアプリのアクティビティに結果を返す場合に役立ちます。結果を受け取るアクティビティがパブリック定数を参照でき、結果コードの値を判断できるためです。
+
+</p>
+
+<p class="note"><strong>注:</strong> 自分のアクティビティが {@link
+android.app.Activity#startActivity startActivity()} または {@link
+android.app.Activity#startActivityForResult startActivityForResult()} を使用して開始されたかどうかをチェックする必要はありません。
+アクティビティを開始したインテントが結果を待っている場合は、{@link
+android.app.Activity#setResult(int,Intent) setResult()} を呼び出します。
+元のアクティビティが {@link
+android.app.Activity#startActivityForResult startActivityForResult()} を呼び出していた場合、
+{@link android.app.Activity#setResult(int,Intent) setResult()} に提供した結果がそこに送られます。それ以外の場合は、結果は無視されます。
+</p>
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/ja/training/basics/intents/index.jd b/docs/html-intl/intl/ja/training/basics/intents/index.jd
new file mode 100644
index 0000000..ac14fd5
--- /dev/null
+++ b/docs/html-intl/intl/ja/training/basics/intents/index.jd
@@ -0,0 +1,62 @@
+page.title=他のアプリとの相互操作
+page.tags=インテント、アクティビティ
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>必要な知識と前提条件</h2>
+<ul>
+ <li>アクティビティのライフサイクルに関する基本知識(<a href="{@docRoot}training/basics/activity-lifecycle/index.html">アクティビティのライフサイクル管理</a>を参照)
+</li>
+</ul>
+
+
+<h2>関連ドキュメント</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">単純なデータの共有</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">ファイルの共有</a>
+ <li><a href="http://android-developers.blogspot.com/2009/11/integrating-application-with-intents.html">Integrating Application with Intents(ブログ投稿)</a>
+</li>
+ <li><a href="{@docRoot}guide/components/intents-filters.html">インテントとインテントフィルタ</a>
+</li>
+</ul>
+
+</div>
+</div>
+
+<p>Android アプリには通常、いくつかの<a href="{@docRoot}guide/components/activities.html">アクティビティ</a>があります。各アクティビティでは、ユーザーが特定のタスク(マップの表示や写真の撮影など)を実行できるユーザー インターフェースが表示されます。あるアクティビティから別のアクティビティにユーザーを移動させるためには、アプリで {@link
+android.content.Intent} を使用して、ある動作に至るアプリの「インテント(意図)」を定義する必要があります。
+
+{@link
+android.app.Activity#startActivity startActivity()} のようなメソッドでシステムに
+{@link android.content.Intent} を渡すと、システムは {@link
+android.content.Intent} を使用して適切なアプリ コンポーネントを特定して起動します。インテントを使用すると、自分のアプリから別のアプリにあるアクティビティを開始させることもできます。
+</p>
+
+<p>{@link android.content.Intent} は、特定のコンポーネント(特定の {@link android.app.Activity} インスタンス)を開始するために<em>明示的</em>にしたり、または(「写真を撮影する」などの)意図したアクションを処理できる任意のコンポーネントを開始するために<em>暗黙的</em>にしたりすることができます。
+
+</p>
+
+<p>このクラスでは {@link android.content.Intent} を使用して、別のアプリを起動する、そのアプリから結果を受け取る、などの他のアプリとの間でいくつかの基本的な相互操作を実行し、他のアプリのインテントに自分のアプリが応答できるようにする方法を示します。
+
+</p>
+
+<h2>レッスン</h2>
+
+<dl>
+ <dt><b><a href="sending.html">別のアプリにユーザーを送る</a></b></dt>
+ <dd>あるアクションを実行する他のアプリを起動するために、暗黙的なインテントを作成する方法を示します。
+</dd>
+ <dt><b><a href="result.html">アクティビティから結果を取得する</a></b></dt>
+ <dd>別のアクティビティを開始し、そのアクティビティの結果を受け取る方法を示します。</dd>
+ <dt><b><a href="filters.html">他のアプリからのアクティビティの開始を許可する</a></b></dt>
+ <dd>自分のアプリが受け入れる暗黙的なインテントを宣言するインテント フィルタを定義することによって、他のアプリからの使用に供するために、自分のアプリ内のアクティビティをオープンにする方法を示します。
+</dd>
+</dl>
+
diff --git a/docs/html-intl/intl/ja/training/basics/intents/result.jd b/docs/html-intl/intl/ja/training/basics/intents/result.jd
new file mode 100644
index 0000000..62c06ae
--- /dev/null
+++ b/docs/html-intl/intl/ja/training/basics/intents/result.jd
@@ -0,0 +1,178 @@
+page.title=アクティビティから結果を取得する
+page.tags=インテント
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>このレッスンでの学習内容</h2>
+<ol>
+ <li><a href="#StartActivity">アクティビティを開始する</a></li>
+ <li><a href="#ReceiveResult">結果を受け取る</a></li>
+</ol>
+
+<h2>関連ドキュメント</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">単純なデータの共有</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">ファイルの共有</a>
+</ul>
+
+ </div>
+</div>
+
+<p>別のアクティビティを開始する場合、必ずしも一方向である必要はありません。別のアクティビティを開始して、結果を受け取ることもできます。
+結果を受け取るには、({@link android.app.Activity#startActivity
+startActivity()} ではなく) {@link android.app.Activity#startActivityForResult
+startActivityForResult()} を呼び出します。</p>
+
+<p>たとえば、自分のアプリでカメラアプリを起動し、結果として撮影した写真を受け取ることができます。または、ユーザーが連絡先を選択するケースにおいて、連絡帳アプリを起動し、結果として連絡先の詳細を受け取ることができます。
+
+</p>
+
+<p>もちろん、応答するアクティビティは結果を返すように設計されていなければなりません。その場合は、別の {@link android.content.Intent} オブジェクトとして結果を送信します。
+自分のアクティビティ側では、
+{@link android.app.Activity#onActivityResult onActivityResult()} コールバック内で結果を受け取ります。</p>
+
+<p class="note"><strong>注: </strong>
+{@link android.app.Activity#startActivityForResult startActivityForResult()} を呼び出す際は、明示的または暗黙的インテントを使用することができます。自分のアクティビティのいずれかを開始して結果を受け取ろうとする場合は、想定通りの結果を受け取れるようにするため、明示的なインテントを使用する必要があります。
+
+</p>
+
+
+<h2 id="StartActivity">アクティビティを開始する</h2>
+
+<p>結果を受け取るためにアクティビティを開始する際、使用する {@link android.content.Intent} オブジェクトに関して特に記すべき内容はありませんが、{@link
+android.app.Activity#startActivityForResult startActivityForResult()} メソッドに対して追加で整数の引数を渡す必要があります。
+</p>
+
+<p>整数の引数は、リクエストを識別する「要求コード」です。結果の
+{@link android.content.Intent} を受け取ると、アプリが正常に結果を識別し、その処理方法を決定することができるように、コールバックが同じ要求コードを提供します。
+</p>
+
+<p>たとえば、ユーザーが連絡先を選択できるようにするアクティビティの開始方法について、次に例を示します。</p>
+
+<pre>
+static final int PICK_CONTACT_REQUEST = 1; // The request code
+...
+private void pickContact() {
+ Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
+ pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
+ startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
+}
+</pre>
+
+
+<h2 id="ReceiveResult">結果を受け取る</h2>
+
+<p>ユーザーが、その後のアクティビティを終えて復帰すると、システムは自分のアクティビティの
+{@link android.app.Activity#onActivityResult onActivityResult()} メソッドを呼び出します。このメソッドには、次の 3 つの引数が含まれます。
+</p>
+
+<ul>
+ <li>{@link
+android.app.Activity#startActivityForResult startActivityForResult()} に渡した要求コード。</li>
+ <li>第 2 のアクティビティによって指定された結果コード。これは、操作が成功した場合の {@link
+android.app.Activity#RESULT_OK} か、ユーザーがバックアウトしたり、何らかの理由で失敗したりした場合の {@link
+android.app.Activity#RESULT_CANCELED} か、いずれか一方です。
+</li>
+ <li>結果のデータを運ぶ {@link android.content.Intent}。</li>
+</ul>
+
+<p>たとえば、「連絡先を選ぶ」インテント用に結果を処理する方法について、次に例を示します。</p>
+
+<pre>
+&#64;Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // Check which request we're responding to
+ if (requestCode == PICK_CONTACT_REQUEST) {
+ // Make sure the request was successful
+ if (resultCode == RESULT_OK) {
+ // The user picked a contact.
+ // The Intent's data Uri identifies which contact was selected.
+
+ // Do something with the contact here (bigger example below)
+ }
+ }
+}
+</pre>
+
+<p>この例では、Android の連絡先または連絡帳アプリから返される結果の {@link android.content.Intent} は、ユーザーが選択した連絡先を識別するコンテンツ {@link android.net.Uri} を提供します。
+
+</p>
+
+<p>正常に結果を処理するためには、結果の
+{@link android.content.Intent} の形式がどうなるかを理解する必要があります。これは、結果を返すアクティビティが自分のアクティビティの 1 つである場合には簡単です。
+Android プラットフォームに付属のアプリでは、特定の結果データに対して役立つ、独自の API を提供しています。
+たとえば、連絡帳アプリ(一部の古いバージョンでは連絡先アプリ)は常に選択した連絡先を識別するコンテンツ URI を含む結果を返し、カメラアプリは別に {@code "data"} で {@link android.graphics.Bitmap} を返します(<a href="{@docRoot}training/camera/index.html">写真を撮影する</a>のクラスを参照)。
+
+
+</p>
+
+
+<h4>ボーナス: 連絡先データを読み取る</h4>
+
+<p>連絡帳アプリから結果を取得する方法を示した上記のコードでは、実際に結果からデータを読み取る方法の詳細には触れていませんが、これは、<a href="{@docRoot}guide/topics/providers/content-providers.html">コンテンツプロバイダ</a>に関する高度な説明が必要であるためです。
+
+
+ここでは興味がある方向けに、結果データをクエリして、選択された連絡先から電話番号を取得する方法について、次にコード例を示します。
+</p>
+
+<pre>
+&#64;Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // Check which request it is that we're responding to
+ if (requestCode == PICK_CONTACT_REQUEST) {
+ // Make sure the request was successful
+ if (resultCode == RESULT_OK) {
+ // Get the URI that points to the selected contact
+ Uri contactUri = data.getData();
+ // We only need the NUMBER column, because there will be only one row in the result
+ String[] projection = {Phone.NUMBER};
+
+ // Perform the query on the contact to get the NUMBER column
+ // We don't need a selection or sort order (there's only one result for the given URI)
+ // CAUTION: The query() method should be called from a separate thread to avoid blocking
+ // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
+ // Consider using {@link android.content.CursorLoader} to perform the query.
+ Cursor cursor = getContentResolver()
+ .query(contactUri, projection, null, null, null);
+ cursor.moveToFirst();
+
+ // Retrieve the phone number from the NUMBER column
+ int column = cursor.getColumnIndex(Phone.NUMBER);
+ String number = cursor.getString(column);
+
+ // Do something with the phone number...
+ }
+ }
+}
+</pre>
+
+<p class="note"><strong>注: </strong>Android 2.3(API レベル 9)以前では、
+{@link android.provider.ContactsContract.Contacts Contacts Provider} でクエリ(上記のような)を実行する場合、自分のアプリで {@link
+android.Manifest.permission#READ_CONTACTS} パーミッション(<a href="{@docRoot}guide/topics/security/security.html">セキュリティとパーミッション</a>を参照)を宣言することが必要です。
+ただし、Android 2.3 からは連絡先または連絡帳アプリにより、結果を返すときに連絡先プロバイダから読み取るための一時的パーミッションが付与されます。
+
+一時的パーミッションは要求された特定の連絡先にのみ適用されるため、{@link
+android.Manifest.permission#READ_CONTACTS} パーミッションを宣言した場合を除き、インテントの {@link android.net.Uri} で指定したもの以外の連絡先はクエリできません。
+
+</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/ja/training/basics/intents/sending.jd b/docs/html-intl/intl/ja/training/basics/intents/sending.jd
new file mode 100644
index 0000000..586bc15
--- /dev/null
+++ b/docs/html-intl/intl/ja/training/basics/intents/sending.jd
@@ -0,0 +1,256 @@
+page.title=別のアプリにユーザーを送る
+page.tags=インテント
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>このレッスンでの学習内容</h2>
+<ol>
+ <li><a href="#Build">暗黙的インテントをビルドする</a></li>
+ <li><a href="#Verify">インテントを受け取るアプリがあるか確認する</a></li>
+ <li><a href="#StartActivity">インテントを使ってアクティビティを開始する</a></li>
+ <li><a href="#AppChooser">アプリ チューザを表示する</a></li>
+</ol>
+
+<h2>関連ドキュメント</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">単純なデータの共有</a></li>
+</ul>
+
+ </div>
+</div>
+
+<p>Android の最も重要な特長の一つに、ユーザーが実行を希望する「アクション」に基づいて、別のアプリにユーザーを送信するアプリの機能があります。
+たとえば、自分のアプリで地図上に表示したいお店やサービスの住所がある場合、アプリでマップを表示するアクティビティをビルドする必要はありません。
+
+代わりに {@link android.content.Intent} 使用して、住所を表示するための要求を作成することができます。
+Android システムは、マップ上に住所を表示できるアプリを起動します。
+</p>
+
+<p>第 1 回のクラス<a href="{@docRoot}training/basics/firstapp/index.html">初めてのアプリ作成</a>で説明したように、自分のアプリでのアクティビティ間を移動するためにインテントを使用する必要があります。通常それには、起動するコンポーネントの正確なクラス名を定義する、<em>明示的なインテント</em>を使用します。
+
+
+ただし、「マップを表示する」などのアクションを別のアプリに実行させたい場合、<em>暗黙的なインテント</em>を使用する必要があります。
+</p>
+
+<p>このレッスンでは、特定のアクションの暗黙的インテントを作成する方法や、他のアプリでアクションを実行するアクティビティを開始させる目的で、暗黙的インテントを使用する方法を示します。
+</p>
+
+
+
+<h2 id="Build">暗黙的インテントをビルドする</h2>
+
+<p>暗黙的インテントは、開始するコンポーネントのクラス名を宣言せず、代わりに実行するアクションを宣言します。
+アクションでは、<em>表示</em>、<em>編集</em>、<em>送信</em>や、<em>取得</em>などの、希望する操作を指定します。
+インテントは、多くの場合、表示対象の住所、送信対象の電子メール メッセージなど、アクションに関連するデータを含みます。作成するインテントにもよりますが、データは {@link android.net.Uri}、またはその他のいくつかのデータ タイプのいずれかとなるか、データ自体全く必要とならない場合もあります。
+
+
+</p>
+
+<p>データが {@link android.net.Uri} である場合は、単純な {@link
+android.content.Intent#Intent(String,Uri) Intent()} コンストラクタを使用してアクションとデータを定義することができます。
+</p>
+
+<p>ここでは、電話番号を指定するための {@link
+android.net.Uri} のデータを使用して、電話をかけるインテントを作成する方法について次の例を示します。</p>
+
+<pre>
+Uri number = Uri.parse("tel:5551234");
+Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
+</pre>
+
+<p>{@link android.app.Activity#startActivity
+startActivity()} を呼び出すことにより、自分のアプリでインテントが起動されると、電話アプリは指定された電話番号への通話を開始します。</p>
+
+<p>ここでは他の 2 つのインテント、およびそのアクションと{@link android.net.Uri} データのペアの例を示します。
+</p>
+
+<ul>
+ <li>マップを表示する:
+<pre>
+// Map point based on address
+Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
+// Or map point based on latitude/longitude
+// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
+Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
+</pre>
+ </li>
+ <li>ウェブ ページを表示する:
+<pre>
+Uri webpage = Uri.parse("http://www.android.com");
+Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
+</pre>
+ </li>
+</ul>
+
+<p>暗黙的インテントのその他の種類には、文字列などのさまざまなデータ タイプを提供する「特別」データを必要とします。
+さまざまな {@link
+android.content.Intent#putExtra(String,String) putExtra()} メソッドを使用して、特別データを 1 つ以上追加することができます。</p>
+
+<p>デフォルトでは、インテントに含まれる
+{@link android.net.Uri} データに基づいて、インテントに必要な適切な MIME タイプをシステムが決定します。インテントに {@link android.net.Uri} が含まれていない場合は、通常は {@link android.content.Intent#setType setType()} を使用して、インテントに関連するデータのタイプを指定する必要があります。
+
+MIME タイプの詳細な指定により、どの種類のアクティビティがインテントを受け取るかが指定されます。
+</p>
+
+<p>ここでは、目的のアクションを指定するための特別データを追加しているインテントの例を示します。</p>
+
+<ul>
+ <li>添付ファイル付きのメールを送信する:
+<pre>
+Intent emailIntent = new Intent(Intent.ACTION_SEND);
+// The intent does not have a URI, so declare the "text/plain" MIME type
+emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
+emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients
+emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
+emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
+emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));
+// You can also attach multiple items by passing an ArrayList of Uris
+</pre>
+ </li>
+ <li>カレンダーイベントを作成する:
+<pre>
+Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
+Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);
+Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);
+calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
+calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
+calendarIntent.putExtra(Events.TITLE, "Ninja class");
+calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");
+</pre>
+<p class="note"><strong>注:</strong> カレンダー イベント用のこのインテントは、API レベル 14 以降でのみサポートされています。
+</p>
+ </li>
+</ul>
+
+<p class="note"><strong>注:</strong> できるだけ具体的に {@link
+android.content.Intent} を定義することが重要です。たとえば、
+{@link android.content.Intent#ACTION_VIEW} のインテントを使用して画像を表示する場合、
+{@code image/*} の MIME タイプを指定する必要があります。これにより、他のタイプのデータを「表示」できる(マップ アプリのような)アプリがインテントによってトリガーされることを回避します。
+</p>
+
+
+
+<h2 id="Verify">インテントを受け取るアプリがあるか確認する</h2>
+
+<p>Android プラットフォームは、特定のインテント(電話、メール、カレンダーアプリなど)が内蔵のアプリのいずれかへ解決することを保証しますが、インテントを呼び出す前に常に検証ステップを含める必要があります。
+
+</p>
+
+<p class="caution"><strong>警告: </strong>インテントを呼び出した際、端末上で利用可能なインテントを処理できるアプリがない場合、アプリがクラッシュします。
+</p>
+
+<p>インテントに応答できる利用可能なアクティビティがあるかどうかを確認するには {@link
+android.content.pm.PackageManager#queryIntentActivities queryIntentActivities()} を呼び出して、
+{@link android.content.Intent} を処理できるアクティビティのリストを取得します。返された {@link
+java.util.List} が空ではない場合、安全にインテントを使用することができます。次に例を示します。</p>
+
+<pre>
+PackageManager packageManager = {@link android.content.Context#getPackageManager()};
+List<ResolveInfo> activities = packageManager.queryIntentActivities(intent,
+ PackageManager.MATCH_DEFAULT_ONLY);
+boolean isIntentSafe = activities.size() > 0;
+</pre>
+
+<p><code>isIntentSafe</code> が <code>true</code> であれば、少なくとも 1 つのアプリがインテントに応答します。
+<code>false</code> であれば、インテントを処理するアプリが存在しません。</p>
+
+<p class="note"><strong>注:</strong> ユーザーがインテントを使用する前にインテントを使用する機能を無効化する必要がある場合、アクティビティが最初に起動するときにこのチェックを実行する必要があります。
+
+インテントを処理できるアプリが具体的に分かっている場合、当該アプリをダウンロードするユーザーのためにリンクを提供することができます(<a href="{@docRoot}distribute/tools/promote/linking.html">Google
+Play 上の自分の製品にリンクする方法</a>を参照)。
+</p>
+
+
+<h2 id="StartActivity">インテントを使ってアクティビティを開始する</h2>
+
+<div class="figure" style="width:200px;margin-top:-10px">
+ <img src="{@docRoot}images/training/basics/intents-choice.png" alt="" />
+ <p class="img-caption"><strong>図 1.</strong> 複数のアプリがインテントを処理することができるときに表示される選択ダイアログの例です。
+</p>
+</div>
+
+<p>{@link android.content.Intent} を作成し、付加情報を設定したら、{@link
+android.app.Activity#startActivity startActivity()} を呼び出してシステムに送信します。システムがインテントを処理することができる複数のアクティビティを特定した場合、図 1 に示すように使用するアプリを選択できるダイアログをユーザーに表示します。
+
+インテントを処理できるアクティビティが 1 つのみの場合、システムはすぐにそのアクティビティを起動します。
+</p>
+
+<pre>
+startActivity(intent);
+</pre>
+
+<p>次に、マップを表示するためのインテントを作成し、そのインテントを処理するアプリが存在するかを確認してから起動する、一連の方法について例を示します。
+</p>
+
+<pre>
+// Build the intent
+Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
+Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
+
+// Verify it resolves
+PackageManager packageManager = {@link android.content.Context#getPackageManager()};
+List&lt;ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
+boolean isIntentSafe = activities.size() > 0;
+
+// Start an activity if it's safe
+if (isIntentSafe) {
+ startActivity(mapIntent);
+}
+</pre>
+
+
+
+<h2 id="AppChooser">アプリ チューザを表示する</h2>
+
+<div class="figure" style="width:200px;margin-top:-10px">
+ <img src="{@docRoot}images/training/basics/intent-chooser.png" alt="" />
+ <p class="img-caption"><strong>図 2.</strong> チューザのダイアログ</p>
+</div>
+
+<p>自分の {@link android.content.Intent} を {@link
+android.app.Activity#startActivity startActivity()} に渡してアクティビティを開始した際に、インテントに応答できる複数のアプリがある場合、ユーザーがデフォルトで使用するアプリを選択できること(ダイアログの下部にあるチェックボックスを選択してこれを行います。図 1 参照)に注意してください。
+
+これは、(1 つのウェブ ブラウザのみを使用する傾向にあるユーザーが)ウェブ ページを開いたり、(1 つのカメラを選ぶ傾向にあるユーザーが)写真を撮影したりするときのように、ユーザーがアクション実行時に毎回同じアプリの使用を希望するような場合には有用です。
+
+</p>
+
+<p>一方、実行対象のアクションが複数のアプリによって処理できる場合、ユーザーは毎回異なるアプリを選ぶかもしれません。たとえば「共有」アクションなど、いくつかのアプリを介してアイテムを共有する可能性があります。この場合、図 2 に示すように、チューザのダイアログを明示的に表示する必要があります。
+
+
+チューザのダイアログは、アクションのたびに使用するアプリを選択するよう、ユーザーを強制します(ユーザーはアクションのデフォルトのアプリを選択することはできません)。
+
+</p>
+
+<p>チューザを表示するには、{@link
+android.content.Intent#createChooser createChooser()} を使用して {@link android.content.Intent} を作成し、{@link
+android.app.Activity#startActivity startActivity()} に渡します。次に例を示します。</p>
+
+<pre>
+Intent intent = 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 chooser
+Intent chooser = Intent.createChooser(intent, title);
+
+// Verify the intent will resolve to at least one activity
+if (intent.resolveActivity(getPackageManager()) != null) {
+ startActivity(chooser);
+}
+</pre>
+
+<p>これにより、{@link
+android.content.Intent#createChooser createChooser()} メソッドに渡されたインテントに応答するアプリのリストを示すダイアログが表示され、指定されたテキストがダイアログのタイトルになります。
+</p>
+
+
+
diff --git a/docs/html-intl/intl/ko/design/get-started/principles.jd b/docs/html-intl/intl/ko/design/get-started/principles.jd
new file mode 100644
index 0000000..aba8a9b
--- /dev/null
+++ b/docs/html-intl/intl/ko/design/get-started/principles.jd
@@ -0,0 +1,307 @@
+page.title=Android 디자인 원칙
+@jd:body
+
+<p>이러한 디자인 원칙은 사용자의 이익을 가장 염두에 두고 Android
+사용자 환경 팀(User Experience Team)에 의해서와 이 팀을 위해 개발되었습니다. Android 개발자 및 디자이너를
+위해 Android 사용자 환경 팀은 계속해서 여러
+유형의 기기를 위한 상세한 디자인 가이드라인의
+기저를 이루고 있습니다.</p>
+
+<p>
+본인의
+창의성과 디자인 사고를 적용할 때 이러한 원칙을 고려해 보시기 바랍니다. 목적을 가지고 여러 가지 참신한 발상을 실현해 보세요.
+</p>
+
+<h2 id="enchant-me">황홀하게 만들기</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="delight-me">놀라운 방식으로 기쁨을 주기</h4>
+<p>아름다운 표면, 신중하게 위치한 애니메이션 또는 시간적으로 잘 짜여진 소리 효과는 사람들에게 즐거운
+경험을 줍니다. 잔잔한 효과는 자연스러움을 느끼게 해주며, 강력한
+힘을 가지고 있다고 느끼게 해줍니다.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_delight.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="real-objects-more-fun">버튼 및 메뉴보다 더 흥미로운 실제 사물</h4>
+<p>사람들이 직접 앱 내 사물을 터치하고 조작할 수 있게 해보세요. 이는 태스크를 수행할 때
+필요한 인지 노력을 줄이는 동시에 정서적인 만족을 가져다 줍니다.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_real_objects.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="make-it-mine">내 것으로 만들게 하기</h4>
+<p>사람들은 개인적인 취향을 더하고 싶어 하는데, 그렇게 하면 마음이 편안해지고 통제할 수 있다고 느끼게 되기 때문입니다. 합리적이고
+아름다운 기본 설정을 제공하는 동시에
+주요 태스크를 저해하지 않는 범위에서 재미있고, 선택 가능한 맞춤 기능을 제공할 것을 고려해 보십시오.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_make_it_mine.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="get-to-know-me">사용자에 대해 파악하기</h4>
+<p>시간이 지남에 따라 사람들이 선호하는 것을 알아보세요. 똑같은 선택을 매번
+하도록 요구하기 보다는 이전 선택을 쉽게 접근할 수 있는 곳에 둡니다.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_get_to_know_me.png">
+
+ </div>
+</div>
+
+<h2 id="simplify-my-life">사용자의 생활을 단순하게 만들기</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="keep-it-brief">간결하게 만들기</h4>
+<p>간단한 단어로 이루어진 짧은 문구를 사용하세요. 문장이 길면 사람들이 보지 않고 넘길 가능성이 커집니다.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_keep_it_brief.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="pictures-faster-than-words">말보다 빠른 사진</h4>
+<p>생각을 전달하는 데 사진을 이용할 것을 고려해 보세요. 사람들의 시선을 끌고 말보다
+더 효과적일 수 있습니다.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_pictures.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="decide-for-me">사용자를 대신해서 결정해 주되 최종 결정권은 사용자에게 주기</h4>
+<p>먼저 물어보기 보다는 최선의 추측을 하고 조치를 취해 보세요. 선택하고 결정해야 하는 사항이 너무 많으면 사람들이
+짜증을 내게 됩니다. 만약을 대비해 '실행 취소' 기능을 제공합니다.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_decide_for_me.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="only-show-when-i-need-it">사용자가 필요로 할 때 필요한 사항만 보여주기</h4>
+<p>사람들은 한 번에 너무 많은 것을 보면 버거워합니다. 태스크 및 정보를 소화 가능한
+작은 크기로 나누세요. 현재 필요하지 않은 옵션은 숨기고 사람들의 작업 진행에 맞게 옵션을 표시하세요.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_information_when_need_it.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="always-know-where-i-am">사용자 자신이 현재 어디에 있는지 항상 알도록 하기</h4>
+<p>사람들에게 현재 자신이 어디에 있는지에 대한 확신을 주어야 합니다. 앱에서 장소가 명확하게 표시되게 하고,
+전환을 사용하여 화면 간 관계를 보여줍니다. 현재 작업 중인 태스크에 대한 피드백을 제공합니다.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_navigation.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="never-lose-my-stuff">사용자가 가지고 있는 것들을 절대 잃어버리지 않도록 하기</h4>
+<p>사람들이 공들여 만든 것을 저장하고 어디서든지 액세스할 수 있게 합니다. 휴대폰, 태블릿 및 컴퓨터에 걸쳐 설정,
+개인적 특색, 그리고 만든 것들이 저장되도록 합니다. 그렇게 하면 업그레이드가 세상에서
+가장 쉬워집니다.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_never_lose_stuff.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="looks-same-should-act-same">똑같이 보이면 똑같이 동작되도록 하기</h4>
+<p>기능을 시각적으로 단순하게 만들기 보다는 눈에 띄게 만들어 사람들이 기능적 차이를 알아볼 수 있게 합니다.
+비슷하게 보이는 장소지만 같은 입력에 대해 다르게 실행되는 모드는 피하도록 합니다.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_looks_same.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="interrupt-only-if-important">중요할 때만 작업을 중단하기</h4>
+<p>유능한 개인 비서와 같이 중요하지 않은 일로 사람들의 작업을 중단하지 않도록 합니다. 사람들은
+작업에 계속 집중하기를 바라며, 중요하고 시간을 다투는 일을 제외하고는 작업이 중단되면 부담스럽고 짜증이 날 수 있습니다.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_important_interruption.png">
+
+ </div>
+</div>
+
+<h2 id="make-me-amazing">사용자를 놀래킬 수 있는 환경 만들기</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="give-me-tricks">어디서든 적용될 수 있는 팁 제공하기</h4>
+<p>사람들은 스스로 알아내는 것을 좋아합니다. 다른 Android 앱의 시각적 패턴과 머슬 메모리(muscle memory)를 활용하여
+앱을 쉽게 배울 수 있게 만드세요. 예를 들어 스와이프 제스처는
+좋은 탐색 지름길이 될 수 있습니다.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_tricks.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="its-not-my-fault">사용자가 자기 탓으로 느끼지 않게 하기</h4>
+<p>사람들의 실수를 바로잡아 줄 때는 부드럽게 합니다. 사람들은
+앱을 사용할 때 스마트하게 느끼고 싶어 합니다. 뭔가 잘못될 경우, 명확한 복구 지침을 제공하되, 기술적인 세부 사항은 제공하지 않습니다.
+사람들 모르게 복구할 수 있으면 더 좋습니다.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_error.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="sprinkle-encouragement">격려하기</h4>
+<p>복잡한 태스크를 쉽게 완료할 수 있도록 여러 단계로 나눕니다. 미묘한 반짝임일지라도
+작업에 대해서 피드백을 줍니다.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_sprinkle_encouragement.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="do-heavy-lifting-for-me">힘든 건 대신해주기</h4>
+<p>초보자들이 할 수 있을 것이라 생각하지 못한 일들을 해서 전문가처럼 느낄 수 있게 합니다. 예를
+들어, 여러 사진 효과를 결합한 단축키 기능은 아마추어 사진이
+겨우 몇 단계를 거치는 것만으로 멋진 사진으로 보이게 할 수 있습니다.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_heavy_lifting.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="make-important-things-fast">중요한 일은 빨리 해결되도록 하기</h4>
+<p>모든 작업이 같지는 않습니다. 앱에서 가장 중요한 것이 무엇인지 결정한 후 쉽게 찾을 수 있고
+빨리 사용할 수 있도록 합니다. 일례로 카메라의 셔터 버튼이나 음악 플레이어의 일시정지 버튼이 이에 해당됩니다.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_make_important_fast.png">
+
+ </div>
+</div>
diff --git a/docs/html-intl/intl/ko/design/material/index.jd b/docs/html-intl/intl/ko/design/material/index.jd
new file mode 100644
index 0000000..31992fa
--- /dev/null
+++ b/docs/html-intl/intl/ko/design/material/index.jd
@@ -0,0 +1,186 @@
+page.title=머티어리얼 디자인
+page.tags=Material,design
+page.type=design
+page.image=design/material/images/MaterialLight.png
+
+@jd:body
+
+<!-- developer docs box -->
+<a class="notice-developers right" href="{@docRoot}training/material/index.html">
+ <div>
+ <h3>개발자 문서</h3>
+ <p>머티어리얼 디자인으로 앱 생성</p>
+ </div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw">
+<div>
+ <h3>비디오</h3>
+ <p>머티어리얼 디자인 소개</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw">
+<div>
+ <h3>비디오</h3>
+ <p>종이와 잉크: 중요한 머티어리얼</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc">
+<div>
+ <h3>비디오</h3>
+ <p>Google I/O 앱 내 머티어리얼 디자인</p>
+</div>
+</a>
+
+
+
+<p itemprop="description">머티어리얼 디자인은 플랫폼 및 기기 전반의 표현 방식, 모션 및
+상호 작용 디자인에 대한 종합적인 지침입니다. Android에는 이제
+머티어리얼 디자인 앱에 대한 지원이 포함되었습니다. Android 앱에서 머티어리얼 디자인을 사용하려면 <a href="http://www.google.com/design/spec">머티어리얼 디자인 사양</a>에
+규정되어 있는 지침을 따르세요. 또한 Android 5.0(API 레벨 21) 이상에서 제공하는
+새 구성 요소 및 기능을 사용하세요.</p>
+
+<p>Android는 머티어리얼 디자인 앱을 구축하는 데 사용할 수 있는 다음 요소를 제공합니다.</p>
+
+<ul>
+ <li>새로운 테마</li>
+ <li>복잡한 뷰를 위한 새로운 위젯</li>
+ <li>사용자 지정 그림자 및 애니메이션을 위한 새로운 API</li>
+</ul>
+
+<p>Android에서 머티어리얼 디자인을 구현하는 방법에 대한 자세한 내용은
+<a href="{@docRoot}training/material/index.html">머티어리얼 디자인으로 앱 생성</a>을 참조하세요.</p>
+
+
+<h3>머티어리얼 테마</h3>
+
+<p>머티어리얼 테마는 앱에 사용할 수 있는 새로운 스타일, 색상표를
+설정할 수 있는 시스템 위젯, 그리고 터치 피드백 및 액티비티 전환을 위한 기본 애니메이션을 제공합니다.</p>
+
+<!-- two columns -->
+<div style="width:700px;margin-top:25px;margin-bottom:20px">
+<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>
+ </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>
+ </div>
+</div>
+<br style="clear:left"/>
+</div>
+
+<p>자세한 내용은 <a href="{@docRoot}training/material/theme.html">머티어리얼
+테마 사용</a>을 참조하세요.</p>
+
+
+<h3>목록 및 카드</h3>
+
+<p>Android는 머티어리얼 디자인 스타일
+및 애니메이션으로 카드 및 목록을 표시하는 데 사용할 수 있는 두 개의 새로운 위젯을 제공합니다.</p>
+
+<!-- two columns -->
+<div style="width:700px;margin-top:25px;margin-bottom:20px">
+<div style="float:left;width:250px;margin-left:40px;margin-right:60px;">
+ <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" />
+ <p>새로운 <code>RecyclerView</code> 위젯은 <code>ListView</code>의
+플러그 기능이 개선된 버전으로, 다양한 레이아웃 유형을 지원하고 향상된 성능을 제공합니다.</p>
+</div>
+<div style="float:left;width:250px;margin-right:0px;">
+ <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" />
+ <p>새로운 <code>CardView</code> 위젯은 일관적인 모양 및 느낌이 있는
+카드 내 정보의 중요한 부분을 표시할 수 있게 해줍니다.</p>
+</div>
+<br style="clear:left"/>
+</div>
+
+<p>자세한 내용은 <a href="{@docRoot}training/material/lists-cards.html">목록
+및 카드 생성</a>을 참조하세요.</p>
+
+
+<h3>뷰 그림자</h3>
+
+<p>X 및 Y 속성과 더불어 이제 Android의 뷰에는 Z
+속성이 추가되었습니다. 이 새로운 속성은 다음을 결정하는 뷰의 엘리베이션을 나타냅니다.</p>
+
+<ul>
+<li>그림자 크기: 뷰의 Z 값이 클수록 표시되는 그림자도 커집니다.</li>
+<li>그리기 순서: 뷰의 Z 값이 클수록 다른 뷰의 위에 표시됩니다.</li>
+</ul>
+
+<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/videos/ContactsAnim.webm"/>
+ <source src="{@docRoot}design/videos/ContactsAnim.ogv"/>
+ </video>
+ </div>
+ <div style="font-size:10pt;margin-left:20px;margin-bottom:30px">
+ <em>영화를 재생하려면 기기 화면을 클릭합니다.</em>
+ </div>
+</div>
+
+<p>자세한 내용은 <a href="{@docRoot}training/material/shadows-clipping.html">그림자
+정의 및 뷰 클리핑</a>을 참조하세요.</p>
+
+
+<h3>애니메이션</h3>
+
+<p>새 애니메이션 API는 UI 컨트롤 내의 터치 피드백, 뷰 상태
+변화, 그리고 액티비티 전환을 위한 사용자 지정 애니메이션을 생성할 수 있게 해줍니다.</p>
+
+<p>이 API를 사용하면 다음 작업을 수행할 수 있습니다.</p>
+
+<ul>
+<li style="margin-bottom:15px">
+<strong>터치 피드백</strong> 애니메이션으로 뷰 내 터치 이벤트에 응답하기.
+</li>
+<li style="margin-bottom:15px">
+<strong>회전하며 나타나기</strong> 애니메이션으로 뷰 감추기 및 표시하기.
+</li>
+<li style="margin-bottom:15px">
+사용자 지정 <strong>액티비티 전환</strong> 애니메이션으로 액티비티 간 전환하기.
+</li>
+<li style="margin-bottom:15px">
+<strong>커브 모션</strong>으로 더 자연스러운 애니메이션 생성하기.
+</li>
+<li style="margin-bottom:15px">
+<strong>뷰 상태 변경</strong> 애니메이션으로 하나 이상의 뷰 속성 변경 사항 애니메이션화하기.
+</li>
+<li style="margin-bottom:15px">
+뷰 상태 변경 간에 <strong>상태 목록 드로어블</strong>에서 애니메이션 표시하기.
+</li>
+</ul>
+
+<p>터치 피드백 애니메이션은 버튼과 같은 여러 기본 뷰에 내장되어 있습니다. 새 API를 사용하면 이러한 애니메이션을 사용자 지정하고 사용자 지정 뷰에 추가할 수
+있습니다.</p>
+
+<p>자세한 내용은 <a href="{@docRoot}training/material/animations.html">사용자지정
+애니메이션 정의</a>를 참조하세요.</p>
+
+
+<h3>드로어블</h3>
+
+<p>드로어블에 대한 다음과 같은 새 기능을 통해 머티어리얼 디자인 앱을 쉽게 구현할 수 있습니다.</p>
+
+<ul>
+<li><strong>벡터 드로어블</strong>은 단색 인앱 아이콘에
+적합하며, 정의 손실 없이 확장 가능합니다.</li>
+<li><strong>드로어블 색조</strong>를 사용하면 비트맵을 알파 마스크로 정의할 수 있으며, 런타임에
+색을 입힐 수 있습니다.</li>
+<li><strong>색상 추출</strong>은
+비트맵 이미지에서 주요 색상을 자동으로 추출할 수 있게 해줍니다.</li>
+</ul>
+
+<p>자세한 내용은 <a href="{@docRoot}training/material/drawables.html">Drawable
+사용</a>을 참조하세요.</p>
diff --git a/docs/html-intl/intl/ko/design/patterns/confirming-acknowledging.jd b/docs/html-intl/intl/ko/design/patterns/confirming-acknowledging.jd
new file mode 100644
index 0000000..2444b0e
--- /dev/null
+++ b/docs/html-intl/intl/ko/design/patterns/confirming-acknowledging.jd
@@ -0,0 +1,70 @@
+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">
+ <img src="{@docRoot}design/media/confirm_ack_confirming.png">
+ <p><strong>확인하기</strong>란, 사용자에게 방금 호출한 작업을 정말로 진행할 것인지 묻는 것입니다. 경우에 따라 확인은 고려해야 할 작업과 관련된 경고 또는 중요한 정보와 함께 표시됩니다.</p>
+ </div>
+ <div class="layout-content-col span-6">
+ <img src="{@docRoot}design/media/confirm_ack_acknowledge.png">
+ <p><strong>승인하기</strong>란, 사용자에게 방금 호출한 작업이 완료되었음을 알리는 텍스트를 표시하는 것입니다. 이는 시스템이 수행하는 암시적인 작업에 대한 불확실성을 제거해 줍니다. 경우에 따라 승인은 작업의 실행을 취소하는 옵션과 함께 표시됩니다.</p>
+ </div>
+</div>
+
+<p>이런 방식의 사용자와의 소통은 이미 일어난 일이나 일어날 일에 대한 불확실성을 완화시키는 데 도움이 될 수 있습니다. 또한, 확인하기 또는 승인하기는 사용자가 후회할지도 모르는 실수를 미연에 방지합니다.</p>
+
+<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">
+ <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">
+ <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">
+ <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">
+ <h4>예: Gmail 대화 삭제</h4>
+ <img src="{@docRoot}design/media/confirm_ack_draft_deleted.png">
+ <p>사용자가 Gmail 목록에서 대화를 삭제하면, 승인이 실행 취소 옵션과 함께 표시됩니다. 승인은 사용자가 목록을 스크롤하는 등의 관련 없는 작업을 수행하기 전까지 그대로 남아 있습니다.</p>
+ </div>
+</div>
+
+<h2>확인 또는 승인이 필요 없는 경우</h2>
+<div class="layout-content-row">
+ <div class="layout-content-col span-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">
+ <h4>예: 홈 화면에서 앱 제거하기</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_removeapp.png">
+ <p><strong>확인이 필요 없습니다</strong>. 이는 의도적인 작업으로, 사용자는 상대적으로 크고 고립된 대상으로 항목을 끌어다 놓을 것입니다. 따라서 실수가 발생할 가능성이 매우 낮습니다. 하지만 사용자가 이 결정을 후회하는 경우, 다시 복구하는 데는 몇 초면 됩니다.</p>
+ <p><strong>승인이 필요 없습니다</strong>. 사용자는 앱이 홈 화면에서 사라진 것을 알게 되는데, 이는 앱을 외부로 끌어서 화면에서 사라지게 했기 때문입니다.</p>
+
+ </div>
+</div>
diff --git a/docs/html-intl/intl/ko/design/patterns/navigation.jd b/docs/html-intl/intl/ko/design/patterns/navigation.jd
new file mode 100644
index 0000000..8e5c30b
--- /dev/null
+++ b/docs/html-intl/intl/ko/design/patterns/navigation.jd
@@ -0,0 +1,213 @@
+page.title=뒤로 및 위로 탐색 기능이 포함된 탐색
+page.tags="navigation","activity","task","up navigation","back navigation"
+page.image=/design/media/navigation_between_siblings_gmail.png
+@jd:body
+
+<a class="notice-developers" href="{@docRoot}training/implementing-navigation/index.html">
+ <div>
+ <h3>개발자 문서</h3>
+ <p>효과적인 탐색 구현하기</p>
+ </div>
+</a>
+
+<p itemprop="description">일관적인 탐색 기능은 전반적인 사용자 환경에 필수적인 요소입니다. 일관성 없고 예상대로 진행되지 않는 기본 탐색은
+사용자에게 많은 실망을 줍니다. Android 3.0에서는
+글로벌 탐색 동작에 중요한 변경 사항을 도입했습니다. 뒤로 및 위로 탐색에 대한
+가이드라인을 꼼꼼히 따르면 사용자가 예상 가능하고 신뢰할 수 있는 탐색 기능이 탑재된 앱을 만들 수 있습니다.</p>
+<p>Android 2.3 이하 버전에서는
+앱 내 탐색 기능을 지원하기 위해 시스템의 <em>뒤로</em> 버튼에 의존했습니다. Android 3.0에서는 작업 모음을 도입함으로써 앱 아이콘 및 왼쪽 방향 캐럿으로 이루어진 2차 탐색 메커니즘인
+<em>위로</em> 버튼이 추가되었습니다.</p>
+
+<img src="{@docRoot}design/media/navigation_with_back_and_up.png">
+
+<h2 id="up-vs-back">위로 및 뒤로 비교</h2>
+
+<p>위로 버튼은 화면
+간의 계층적 관계를 기반으로 앱 내에서 탐색할 때 사용됩니다. 예를 들어, 화면 A에 표시된 항목 목록에서 항목을 선택하면 항목에 대한 세부 정보를 표시하는 화면 B로 이동하게 되는데, 이때
+화면 B는 화면 A로
+돌아가는 위로 버튼을 제공해야 합니다.</p>
+<p>화면이 앱의 최상단에 있는 경우(즉, 앱의 홈인 경우), 위로
+버튼이 표시되지 않아야 합니다.</p>
+
+<p>시스템의 뒤로 버튼은 사용자가 최근에 작업한 화면
+기록을 역순으로 탐색할 때 사용됩니다. 일반적으로 이 버튼은 앱의 계층 구조가 아닌 화면
+간의 일시적인 관계를 기반으로 합니다.</p>
+
+<p>또한, 앞서 본 화면이 현재 화면의 계층적 상위 화면일 경우
+뒤로 버튼을 누르는 것과 위로 버튼을 누르는 것의 결과가 동일하며, 이는 흔하게
+발생하는 동작입니다. 하지만 사용자가 앱 내에 머무는 위로 버튼과 달리, 뒤로
+버튼을 누르면 홈 화면 또는 다른 앱으로 돌아갈 수 있습니다.</p>
+
+<img src="{@docRoot}design/media/navigation_up_vs_back_gmail.png">
+
+<p>뒤로 버튼은 화면 간 탐색과 직접적으로 관련 없는 몇 가지 동작도 지원합니다.
+</p>
+<ul>
+<li>부동 창 해제(대화 상자, 팝업)</li>
+<li>상황에 맞는 작업 모음 해제 및 선택한 항목에서 강조 표시 제거</li>
+<li>화상 키보드(IME) 감추기</li>
+</ul>
+<h2 id="within-app">앱 내 탐색</h2>
+
+<h4>진입 지점이 여러 개인 화면으로 이동하기</h4>
+<p>일부 화면은 앱의 계층 구조 내에서 엄격한 위치를 가지고 있지 않는 경우가 있으며, 이 경우 여러 진입 지점을
+통해서 접근할 수 있습니다. 예를 들어 설정 화면은 앱
+내의 다른 어떤 화면에서도 접근이 가능합니다. 이러한 경우, 위로 버튼을 누르면 뒤로 버튼과
+동일하게 참조하는 화면으로 돌아가게 됩니다.</p>
+<h4>화면 내에서 뷰 변경하기</h4>
+<p>화면의 뷰 옵션 변경은 위로 또는 뒤로 버튼의 동작을 변경하지 않습니다. 이는 화면이 앱 계층 구조 내에서 여전히 동일한 위치에
+있고, 어떠한 탐색 기록도 새로 생성되지 않기 때문입니다.</p>
+<p>이러한 뷰 변경의 예는 다음과 같습니다.</p>
+<ul>
+<li>탭 및/또는 좌우 스와이프를 사용하여 뷰 전환하기</li>
+<li>드롭다운(겹쳐진 탭이라고도 함)을 사용하여 뷰 전환하기</li>
+<li>목록 필터링하기</li>
+<li>목록 정렬하기</li>
+<li>표시 문자 변경하기(예: 확대/축소)</li>
+</ul>
+<h4>형제 화면 간 탐색하기</h4>
+<p>항목 목록에서 개별 항목의 상세 뷰로의 이동을 앱에서 지원하는 경우, 해당 항목에서 목록의 이전/이후
+항목으로 직접 이동할 수 있도록 지원하는 것이 바람직한
+경우도 있습니다. 예를 들어 Gmail의 대화에서 왼쪽 또는 오른쪽으로 간단하게 스와이프하여 동일한 받은 편지함에 있는 신규 또는 이전 메일을
+볼 수 있습니다. 화면 내에서 뷰를 변경하는 것과 마찬가지로,
+탐색은 위로 또는 뒤로 버튼의 동작을 바꾸지 않습니다.</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_gmail.png">
+
+<p>하지만 참조 목록으로 같이
+묶여 있지 않은 연관된 상세 뷰 사이를 탐색할 때는 주목할 만한 예외적인 상황이 발생합니다. 예를 들어, Play Store에서
+동일한 개발자가 만든 여러 앱 또는 동일한 아티스트의 여러 앨범을 탐색하는 경우가 그렇습니다. 이러한 경우, 링크를 따라갈 때마다
+기록이 생성되므로, 뒤로 버튼을 누르면 이전에 본 화면으로 이동합니다. 위로 버튼을 누르면 계속해서 이러한 연관된 화면을
+거치지 않고 가장 최근에 본 컨테이너 화면으로 이동합니다.</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_market1.png">
+
+<p>상세
+뷰에 대한 지식을 바탕으로 더욱 스마트한 위로 버튼 동작을 구현할 수 있습니다. 위에서 설명한 Play Store 예를 확장하여 사용자가
+마지막으로 본 도서에서 해당 도서를 각색한 영화의 세부 정보 화면으로 이동했다고 가정해 봅니다. 그러한 경우, 위로 버튼을 누르면 사용자가 이전에 탐색한 적이 없는
+컨테이너(영화)로 이동할 수 있습니다.</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_market2.png">
+
+<h2 id="into-your-app">홈 화면 위젯 및 알림을 통한 앱 탐색</h2>
+
+<p>홈 화면 위젯이나 알림을 사용하여 사용자가 앱 계층 구조 내에
+있는 화면으로 바로 이동할 수 있게 할 수 있습니다. 예를 들어, Gmail의 받은 편지함 위젯과 새 메시지 알림은
+모두 받은 편지함 화면을 건너뛰고 사용자가 해당 메일로 바로 이동할 수 있게 해줍니다.</p>
+
+<p>이러한 두 경우 모두 위로 버튼을 다음과 같이 처리합니다.</p>
+
+<ul>
+<li><em>일반적으로 목적지 화면이
+앱 내의 특정 화면에서 출발한 경우</em>, 위로 버튼은 해당 화면으로 이동해야 합니다.</li>
+<li><em>그 외의 경우</em>, 위로 버튼은 앱의 최상위("홈") 화면으로 이동해야 합니다.</li>
+</ul>
+
+<p>뒤로 버튼의 경우,
+앱의 최상위 화면으로 이동하는 완전한 상위 탐색 경로를 태스크의 백 스택에 삽입하여 탐색을 더욱 예측 가능하게 만들어야 합니다. 이는 앱에 어떻게 진입했는지 잊어버린
+사용자가 앱에서 나가기
+전에 앱의 최상위 화면으로 이동할 수 있게 해줍니다.</p>
+
+<p>예를 들어 Gmail의 홈 화면 위젯은 메일 작성
+화면으로 바로 진입할 수 있는 버튼을 제공합니다. 메일 작성 화면에서 위로 또는
+뒤로 버튼을 누르면 받은 편지함으로 이동하게 되고, 받은 편지함에서 뒤로 버튼을 누르면 홈으로 돌아가게 됩니다.</p>
+
+<img src="{@docRoot}design/media/navigation_from_outside_back.png">
+
+<h4>간접 알림</h4>
+
+<p>앱이 동시에 다양한 이벤트 정보를 제공해야 하는 경우, 사용자를 틈새 화면(interstitial screen)으로 이동하게 하는
+단일 알림을 사용할 수 있습니다. 이 화면은
+이러한 이벤트를 요약하고, 사용자가 앱을 세부적으로 탐색할 수 있는 경로를 제공합니다. 이러한 스타일의 알림을 <em>간접 알림</em>이라고
+합니다.</p>
+
+<p>기본(직접) 알림과 달리, 간접 알림의
+틈새 화면에서 뒤로 버튼을 누르면 백 스택에 다른 화면이
+추가되지 않고 알림이 트리거된 지점으로 사용자를 이동시킵니다. 사용자가
+틈새 화면에서 앱으로 들어가면, 위로 버튼 및 뒤로 버튼은 위에서 설명한 바와 같이 틈새 화면으로 돌아가지 않고, 기본 알림과 마찬가지로 앱 내에서
+탐색을 수행합니다.</p>
+
+<p>예를 들어 Gmail을 사용 중인 사용자가 캘린더로부터 간접 알림을 받았다고 가정해 봅니다. 해당
+알림을 터치하면 틈새 화면이 열립니다. 이 화면에는 다른
+여러 이벤트에 대한 알림도 표시됩니다. 틈새 화면에서 뒤로 버튼을 터치하면 Gmail로 돌아갑니다. 특정
+이벤트를 터치하면 사용자를 틈새 화면에서 나오게 하여
+해당 이벤트의 세부 정보를 보여주는 완전한 캘린더 앱으로 이동하게 됩니다. 이벤트 세부 정보 화면에서 위로 버튼과 뒤로 버튼을 누르면 캘린더의 최상위 뷰로 이동하게 됩니다.</p>
+
+<img src="{@docRoot}design/media/navigation_indirect_notification.png">
+
+<h4>팝업 알림</h4>
+
+<p><em>팝업 알림</em>은 알림 창을 거치지 않고 바로 사용자에게
+표시되는 알림입니다. <strong>팝업 알림은 시기적절한
+응답이 요구되는 경우와 사용자의 컨텍스트를 중단하는 것이 필요한 경우에 한하여</strong> 드물게 사용됩니다. 예를 들어
+Talk는 친구가 화상 채팅에 참여하도록 보낸
+초대를 사용자에게 알리기 위해 이러한 스타일의 알림을 사용하며, 이 초대는 몇 초 후에 자동으로 만료됩니다.</p>
+
+<p>탐색 동작 측면에서, 팝업 알림은 간접
+알림의 틈새 화면 동작을 상당히 많이 따릅니다. 뒤로 버튼을 누르면 팝업 알림이 해제됩니다. 사용자가 팝업을
+통해 앱으로 이동하면, 위로 및 뒤로 버튼은 기본 알림의 규칙에 따라 앱 내에서
+탐색합니다.</p>
+
+<img src="{@docRoot}design/media/navigation_popup_notification.png">
+
+<h2 id="between-apps">앱 간 탐색</h2>
+
+<p>Android 시스템의 기본이 되는 강점 중 하나는 앱이
+다른 앱을 실행할 수 있다는 점이며, 이로 인해 사용자는 한 앱에서 다른 앱으로 직접 이동할 수 있습니다. 예를 들어, 사진을 캡처해야 하는
+앱은 카메라 앱을 작동시킬 수 있으며, 카메라 앱은 사진을 해당 앱으로
+돌려줍니다. 이러한 기능은 개발자와 사용자 모두에게 매우 유용합니다. 왜냐하면 개발자는 쉽게 다른 앱의
+코드를 활용할 수 있고, 사용자는 흔히 수행하는
+작업을 일관된 환경으로 즐길 수 있기 때문입니다.</p>
+
+<p>앱 간 탐색을 이해하려면 아래에서
+설명하는 Android 프레임워크 동작을 알아야 합니다.</p>
+
+<h4>액티비티, 태스크 및 인텐트</h4>
+
+<p>Android에서 <strong>액티비티</strong>는
+정보 및 사용자가 수행할 수 있는 모든 관련 작업이 포함된 화면을 정의하는 애플리케이션 구성 요소입니다. 앱은 본인이 직접 생성하는
+액티비티와 다른 앱에서 재활용하는 액티비티로 구성되어 있는 액티비티 컬렉션입니다.</p>
+
+<p><strong>태스크</strong>는 사용자가 목적을 달성하기 위해서 따르는 일련의 액티비티입니다. 단일
+태스크는 단 한 가지 앱의 액티비티만 사용할 수도 있고,
+여러 앱의 액티비티를 사용할 수도 있습니다.</p>
+
+<p><strong>인텐트</strong>는 어떤 앱이 작업을 수행하는 데 다른
+앱의 도움을 받고자 한다는 신호를 보내는 메커니즘입니다. 앱의 액티비티는
+어떠한 인텐트에 응답을 보낼 수 있는지 알려줄 수 있습니다. "공유하기"와 같이 일반적인 인텐트의 경우, 사용자는 해당 요청을 수행할 수 있는 여러 앱을
+설치했을 수도 있습니다.</p>
+
+<h4>예: "공유하기"를 지원하는 앱 간에 탐색하기</h4>
+
+<p>액티비티, 태스크, 인텐트가 어떻게 같이 동작하는지 이해하려면 한 앱이 다른 앱을 사용하여 콘텐츠
+공유를 어떻게 가능하게 하는지 생각해 보세요. 예를 들어, 홈에서 Play Store 앱을 실행하면
+새로운 태스크 A가 시작됩니다(아래 그림 참조). Play Store에서 탐색하다가 홍보 도서의 세부 정보를
+보기 위해 터치하면, 다른 액티비티를 추가하여 태스크를 연장하는 방식으로 사용자는 동일한 태스크에 머물게 됩니다. 공유하기
+작업을 트리거하면 공유하기 인텐트를 처리하도록
+등록된 액티비티(다양한 앱에서 제공)가 나열된 목록을 보여주는 대화 상자가 표시됩니다.</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_inward.png">
+
+<p>사용자가 Gmail을 통해 공유하기를 선택할 경우, 새로운 태스크가 생성되는 것이 아니라
+태스크 A의 연장으로 Gmail의 메일 작성 액티비티가 추가됩니다. Gmail의 백그라운드에서 실행되는 자체적인 태스크가 있을 경우, 해당 태스크는 아무런
+영향도 받지 않습니다.</p>
+
+<p>메일 작성 액티비티에서 메시지를 보내거나 뒤로 버튼을 터치하면, 사용자는
+도서 세부 정보 액티비티로 돌아가게 됩니다. 뒤로 버튼을 연이어 터치하면 Play
+Store에서 탐색한 페이지로 되돌아가게 되어 결국에는 홈 화면에 이르게 됩니다.</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_back.png">
+
+<p>하지만 사용자가 메일 작성 액티비티에서 위로 버튼을 터치하는 것은
+Gmail에 남아 있고자 하는 의지를 보이는 것입니다. 따라서, 이 경우 Gmail의 대화 목록 액티비티가 표시되고, 새로운 태스크 B가 생성됩니다. 새로운 태스크는
+항상 홈에 기반을 두고 있기 때문에, 대화 목록에서 뒤로 버튼을 터치하면 홈으로 되돌아가게 됩니다.</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_up.png">
+
+<p>태스크 A는 백그라운드에 남아 있기 때문에 나중에 돌아올 수 있습니다(예를 들어,
+최근 앱 화면을 통해). Gmail에 이미 백그라운드에서 실행 중인 자체적인 태스크가 있을 경우,
+해당 태스크는 태스크 B로 대체됩니다. 이전 컨텍스트는 사용자의 새로운 목적에 따라 제거됩니다.</p>
+
+<p>앱 계층 구조 내의 액티비티에서 인텐트를 처리하도록 앱에서 등록하는 경우, 위로 탐색을 지정하는 방법에 대한 지침을 확인하려면
+<a href="#into-your-app">홈 화면 위젯 및
+알림을 통한 앱 탐색</a>을 참조하세요.</p>
diff --git a/docs/html-intl/intl/ko/design/patterns/notifications.jd b/docs/html-intl/intl/ko/design/patterns/notifications.jd
new file mode 100644
index 0000000..aab5eac
--- /dev/null
+++ b/docs/html-intl/intl/ko/design/patterns/notifications.jd
@@ -0,0 +1,872 @@
+page.title=알림
+page.tags="notifications","design","L"
+@jd:body
+
+ <a class="notice-developers" href="{@docRoot}training/notify-user/index.html">
+ <div>
+ <h3>개발자 문서</h3>
+ <p>사용자에게 알리기</p>
+ </div>
+</a>
+
+<a class="notice-designers" href="notifications_k.html">
+ <div>
+ <h3>Android 4.4 이하 버전의 알림</h3>
+ </div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=Uiq2kZ2JHVY">
+<div>
+ <h3>비디오</h3>
+ <p>DevBytes: Android L Developer Preview의 알림</p>
+</div>
+</a>
+
+<style>
+ .col-5, .col-6, .col-7 {
+ margin-left:0px;
+ }
+</style>
+
+<p>알림 시스템을 사용하면 친구로부터 받은 새 채팅 메시지나 캘린더 이벤트와 같이 앱에서 관련된
+시기 적절한
+이벤트에 대한 알림을 사용자에게 표시할 수 있습니다.
+알림을 중요한
+이벤트가
+발생한 경우 사용자에게 이에 대해 알리는 뉴스 채널이나 사용자가 앱에 집중하고
+있지 않은 동안에 이벤트를 시간순으로 기록하는 로그라고 생각하세요. 또한, 적절한 경우 모든 Android 기기에 걸쳐 동기화될 수도 있습니다.</p>
+
+<h4 id="New"><strong>Android 5.0의 새로운 기능</strong></h4>
+
+<p>Android 5.0에서는 구조적,
+시각적, 그리고 기능적으로 중요한 업데이트를 알림을 통해 받을 수 있습니다.</p>
+
+<ul>
+ <li>새로운
+머티어리얼 디자인 테마와 일치하도록 알림이 시각적으로 바뀌었습니다.</li>
+ <li> 알림이 이제 기기 잠금 화면에 표시되나,
+민감한 콘텐츠는 여전히
+숨길 수 있습니다.</li>
+ <li>기기가 사용 중일 때 수신되는 최우선 순위의 알림은 이제
+헤드업 알림이라는 새로운 형식을 사용합니다.</li>
+ <li>클라우드와 동기화되는 알림: Android
+기기 중 하나에서 알림을 해지하면
+다른 기기에서도 해지됩니다.</li>
+</ul>
+
+<p class="note"><strong>참고:</strong> 이
+Android 버전의 알림 디자인은 이전 버전과 많이
+다릅니다. 이전
+버전의 알림 디자인에 대한 자세한 내용은 <a href="./notifications_k.html">Android 4.4 이하 버전의 알림</a>을 참조하세요.</p>
+
+<h2 id="Anatomy">알림의 해부학적 구조</h2>
+
+<p>이 섹션에서는 알림의 기본적인 부분과 다양한 유형의 기기에서 알림이 어떻게
+표시될 수 있는지에 대해 살펴봅니다.</p>
+
+<h3 id="BaseLayout">기본 레이아웃</h3>
+
+<p>모든 알림은 기본적으로 다음을 포함하는 기본 레이아웃으로 구성됩니다.</p>
+
+<ul>
+ <li> 알림 <strong>아이콘</strong>. 알림 아이콘은
+알림을 발생시킨 앱을 나타냅니다. 또한,
+앱이 두 가지 이상의
+유형을 생성하는 경우 알림 유형을 나타낼 수도 있습니다.</li>
+ <li> 알림 <strong>제목</strong> 및 추가
+<strong>텍스트</strong>.</li>
+ <li> <strong>타임스탬프</strong>.</li>
+</ul>
+
+<p>이전 플랫폼 버전의
+{@link android.app.Notification.Builder Notification.Builder}로 생성된 알림은 시스템이 대신
+처리하는 사소한 스타일 변화를 제외하면 Android
+5.0에서 똑같이 표시되고 동작합니다. 이전
+Android 버전의 알림에 대한 자세한 내용은
+<a href="./notifications_k.html">Android 4.4 이하 버전의 알림</a>을 참조하세요.</p></p>
+
+
+ <img style="margin:20px 0 0 0" src="{@docRoot}images/android-5.0/notifications/basic_combo.png" alt="" width="700px" />
+
+
+<div style="clear:both;margin-top:20px">
+ <p class="img-caption">
+ 핸드헬드 알림(왼쪽) 및 Wear에서 표시되는 동일한 알림(오른쪽)의 기본 레이아웃
+- 사용자 사진 및 알림 아이콘 포함
+ </p>
+ </div>
+
+<h3 id="ExpandedLayouts">확장 레이아웃</h3>
+
+
+<p>앱 알림이 얼마나 자세한 정보를
+제공하도록 할지는 직접 선택할 수 있습니다. 메시지의 처음
+몇 줄을 보여주거나 더 큰 이미지 미리보기를 보여줄 수 있습니다. 이러한 추가
+정보는 사용자에게 더 많은
+컨텍스트를 제공하며, 경우에 따라 이를 통해 사용자는 메시지
+전체를 읽을 수도 있습니다. 사용자는
+핀치-줌(pinch-zoom) 또는 한 손가락으로 밀기를 이용하여 축소 레이아웃과
+확장 레이아웃 간을 전환할 수 있습니다.
+ Android는 단일 이벤트 알림에 대해 세 개의 확장 레이아웃
+템플릿(텍스트, 받은 편지함,
+이미지)을 애플리케이션에 사용할 수 있도록 제공합니다. 다음 이미지는
+단일 이벤트 알림이
+핸드헬드(왼쪽) 및 웨어러블(오른쪽)에서 어떻게 표시되는지 보여줍니다.</p>
+
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/expandedtext_combo.png"
+ alt="" width="700px" height;="284px" />
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/stack_combo.png"
+ alt="" width="700px" height;="284px" />
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/ExpandedImage.png"
+ alt="" width="311px" height;="450px" />
+
+<h3 id="actions" style="clear:both; margin-top:40px">작업</h3>
+
+<p>Android는 알림의
+맨 아래 부분에 표시되는 선택적인 작업을 지원합니다.
+이러한 작업을 통해 사용자는 알림을 발생시킨
+애플리케이션을 열 필요 없이 알림 창에서 특정
+알림에 대한 가장 일반적인 태스크를 처리할 수 있습니다.
+이 기능은 밀어서 해제하기와 함께 작용하여 상호 작용의 속도를 향상시키며, 사용자가 자신에게 중요한 알림에
+집중하는 데 도움이 됩니다.</p>
+
+
+ <img src="{@docRoot}images/android-5.0/notifications/action_combo.png" alt="" width="700px" />
+
+
+
+<p style="clear:both">알림에
+포함할 작업의 수는 신중하게 결정해야 합니다. 더 많은
+작업을 포함할수록 인지적 복합성이 가중됩니다. 당장에 중요하며 의미
+있는 작업만 포함하여 작업
+수를 최소한으로
+제한해야 합니다.</p>
+
+<p>알림에 포함하기에 적합한 작업은 다음과 같습니다.</p>
+
+<ul>
+ <li> 표시하려는
+콘텐츠 유형과 관련하여 필수적이고, 자주 사용되며 전형적인 작업
+ <li> 사용자가 신속하게 태스크를 완료할 수 있게 하는 작업
+</ul>
+
+<p>다음과 같은 작업은 피합니다.</p>
+
+<ul>
+ <li> 애매모호한 작업
+ <li> "읽기" 또는
+"열기"와 같이 알림의 기본 작업과 동일한 작업
+</ul>
+
+
+
+<p>작업
+아이콘 및 이름으로 각각 구성된, 최대 세 개의 작업을 지정할 수 있습니다.
+ 단순한 기본 레이아웃에 작업을 추가하면 알림이 확장 가능하게 되며,
+알림에
+확장 레이아웃이 없는 경우에도 이러한 사항이 적용됩니다. 작업은
+확장된
+알림에서만 표시되고 그 외에는 숨겨져 있으므로
+사용자가 알림에서
+호출할 수 있는 모든 작업을 관련 애플리케이션 내에서도
+사용할 수 있는지 확인해야 합니다.</p>
+
+<h2 style="clear:left">헤드업 알림</h2>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/hun-example.png" alt="" width="311px" />
+ <p class="img-caption">
+ 몰입형 앱의
+최상위에
+표시되는 헤드업 알림의 예(걸려오는 전화, 최우선 순위)
+ </p>
+</div>
+
+<p>최우선 순위의 알림을 수신하면(오른쪽), 가능한 작업을 보여주는 확장된 레이아웃 형태로
+잠시 동안 사용자에게
+표시됩니다.</p>
+<p> 그런 다음, 알림이 알림
+창으로 돌아갑니다. 알림에 대한 <a href="#correctly_set_and_manage_notification_priority">우선 순위</a> 플래그가 HIGH, MAX 또는 전체 화면으로
+지정된 경우 헤드업 알림이 표시됩니다.</p>
+
+<p><b>헤드업 알림의 좋은 예</b></p>
+
+<ul>
+ <li> 기기 사용 시 걸려오는 전화</li>
+ <li> 기기 사용 시 알람</li>
+ <li> 새 SMS 메시지</li>
+ <li> 배터리 부족</li>
+</ul>
+
+<h2 style="clear:both" id="guidelines">가이드라인</h2>
+
+
+<h3 id="MakeItPersonal">개인에 맞게 만들기</h3>
+
+<p>다른 사람이 보낸 항목(메시지 또는
+상태 업데이트)에 대한 알림의 경우
+{@link android.app.Notification.Builder#setLargeIcon setLargeIcon()}을 사용하여 그 사람의 이미지를 포함합니다. 또한
+그 사람에 대한 정보를 알림의 메타데이터에 추가합니다({@link android.app.Notification#EXTRA_PEOPLE} 참조).</p>
+
+<p>알림의 기본 아이콘이 여전히 표시됩니다. 따라서 사용자는
+해당 아이콘을 상태 표시줄에
+보이는 아이콘과 관련시킬 수 있습니다.</p>
+
+
+<img src="{@docRoot}images/android-5.0/notifications/Triggered.png" alt="" width="311px" />
+<p style="margin-top:10px" class="img-caption">
+ 누가 트리거했는지와 보낸 내용을 보여주는 알림입니다.
+</p>
+
+
+<h3 id="navigate_to_the_right_place">적합한 곳으로 이동하기</h3>
+
+<p>사용자가 작업
+버튼 외부에서 알림을 터치하면, 사용자가 알림에서
+참조되는 데이터를 확인하고 처리할 수 있는 곳에서
+앱이 열리도록 합니다. 대부분의 경우, 메시지와 같은 단일 데이터 항목을 표시하는 상세 뷰가 이에 해당합니다.
+하지만 알림이 중첩되어 있을 경우에는
+요약 뷰일 수도 있습니다. 앱이
+최상위 레벨 아래의 위치에서 열린 경우
+사용자가 시스템의 뒤로 버튼을 눌러 최상위 레벨로 돌아갈 수 있도록 앱의 백 스택에 탐색 경로를 삽입합니다. 자세한 내용은
+<a href="{@docRoot}design/patterns/navigation.html#into-your-app">탐색</a>
+디자인 패턴의 <em>홈 화면 위젯 및 알림을 통한 앱 탐색</em>을 참조하세요.</p>
+
+<h3 id="correctly_set_and_manage_notification_priority">알림의
+우선 순위를 정확하게 설정하고
+관리하기</h3>
+
+<p>Android는 알림 우선 순위 플래그를 지원합니다. 이 플래그를 통해 다른 알림에 상대적으로 알림이 표시되는 위치가
+결정되도록 할 수 있습니다. 또한
+사용자가 가장 중요한 알림을 항상 가장 먼저 볼 수 있게
+할 수 있습니다. 알림을 게시할 때
+다음 우선 순위 중에서
+선택할 수 있습니다.</p>
+<table>
+ <tr>
+ <td class="tab0">
+<p><strong>우선 순위</strong></p>
+</td>
+ <td class="tab0">
+<p><strong>용도</strong></p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>MAX</code></p>
+</td>
+ <td class="tab1">
+<p>시간에 민감한
+또는
+특정 태스크를 계속 진행하기 전에 처리해야 할
+상황을 사용자에게 알리는 중요하고 긴급한 알림에 사용합니다.</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>HIGH</code></p>
+</td>
+ <td class="tab1">
+<p>중요한 대화에 주로 사용합니다. 일례로 사용자에게 특별히 흥미로운 내용이 포함된 메시지 또는 채팅
+이벤트가 이에 해당합니다.
+최우선 순위의 알림은 헤드업 알림이 표시되도록 합니다.</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>DEFAULT</code></p>
+</td>
+ <td class="tab1">
+<p>여기서 설명하지 않은 기타 모든 우선 순위의 알림에 사용합니다.</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>LOW</code></p>
+</td>
+ <td class="tab1">
+<p>사용자에게 알려야 하지만 긴급하지 않은
+알림에 사용합니다. 우선 순위가 낮은 알림은 보통 목록의 맨 아래에 표시되며,
+공개 또는 대상이 불특정한 소셜 업데이트에 사용하기
+좋습니다. 사용자가
+요구한
+알림이지만, 이러한 알림은 긴급하거나 직접적인
+대화를 우선할 수 없습니다.</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>MIN</code></p>
+</td>
+ <td class="tab1">
+<p>날씨 정보 또는 상황에 맞는
+위치 정보와 같은 상황별 또는 배경 정보에 사용합니다.
+최소 우선 순위 알림은 상태 표시줄에 표시되지 않습니다. 이러한 알림은 사용자가 알림 창을 확대하면
+볼 수 있습니다.</p>
+</td>
+ </tr>
+</table>
+
+
+<h4 id="how_to_choose_an_appropriate_priority"><strong>
+적절한
+우선 순위를 선택하는 방법</strong></h4>
+
+<p><code>DEFAULT</code>, <code>HIGH</code> 및 <code>MAX</code>는 작업을 중단시키는 우선 순위이며, 사용자의 액티비티를
+중단시키는
+위험 요소입니다. 앱 사용자를 성가시게 하지 않으려면 다음과 같은
+알림에만 작업을 중단시키는 우선 순위를 지정해야 합니다.</p>
+
+<ul>
+ <li> 다른 사람이 관련된 알림</li>
+ <li> 시간에 민감한 알림</li>
+ <li> 실제 환경에서의 사용자 행동을 즉시 바꿀 수 있는 알림</li>
+</ul>
+
+<p><code>LOW</code> 및 <code>MIN</code>으로 설정된 알림도 사용자에게
+중요할 수 있습니다. 대부분은 아니지만 많은 알림이 사용자의
+즉각적인 주의를 필요로 하지 않거나 사용자의 손목에 진동을 줄 필요가 없지만, 사용자가 알림을 확인하고자
+했을 때 유용하다고
+여길 정보를 포함합니다. <code>LOW</code> 및 <code>MIN</code>
+우선 순위 알림에 대한 조건은 다음과 같습니다.</p>
+
+<ul>
+ <li> 다른 사람이 관련되지 않음</li>
+ <li> 시간에 민감하지 않음</li>
+ <li> 사용자가 흥미를 가질 만하지만 시간이 있을 때
+보기를 원할 수 있는 내용을 포함함</li>
+</ul>
+
+
+ <img src="{@docRoot}images/android-5.0/notifications/notifications_pattern_priority.png" alt="" width="700" />
+
+
+<h3 style="clear:both" id="set_a_notification_category">알림
+범주 설정하기</h3>
+
+<p>알림이 미리 정의된 범주에 포함될 경우(아래
+참조),
+그에 따라 할당합니다. 알림 창(또는
+다른 알림
+수신자)과 같은 시스템 UI의 기능은 순위 및 필터링 결정을 내리는 데 이 정보를 활용할 수 있습니다.</p>
+<table>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_CALL">CATEGORY_CALL</a></code></p>
+</td>
+ <td>
+<p>수신 전화(음성 또는 화상) 또는 이와 유사한 동기적 대화
+요청</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_MESSAGE">CATEGORY_MESSAGE</a></code></p>
+</td>
+ <td>
+<p>수신되는 직접 메시지(SMS, 인스턴트 메시지 등)</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_EMAIL">CATEGORY_EMAIL</a></code></p>
+</td>
+ <td>
+<p>비동기적 대량 메시지(이메일)</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_EVENT">CATEGORY_EVENT</a></code></p>
+</td>
+ <td>
+<p>캘린더 이벤트</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_PROMO">CATEGORY_PROMO</a></code></p>
+</td>
+ <td>
+<p>홍보 또는 광고</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_ALARM">CATEGORY_ALARM</a></code></p>
+</td>
+ <td>
+<p>알람 또는 타이머</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_PROGRESS">CATEGORY_PROGRESS</a></code></p>
+</td>
+ <td>
+<p>장기간 실행 중인 백그라운드 작업의 진행 상황</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SOCIAL">CATEGORY_SOCIAL</a></code></p>
+</td>
+ <td>
+<p>소셜 네트워크 또는 공유 업데이트</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_ERROR">CATEGORY_ERROR</a></code></p>
+</td>
+ <td>
+<p>백그라운드 작업 또는 인증 상태 오류</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_TRANSPORT">CATEGORY_TRANSPORT</a></code></p>
+</td>
+ <td>
+<p>재생에 대한 미디어 전송 제어</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SYSTEM">CATEGORY_SYSTEM</a></code></p>
+</td>
+ <td>
+<p>시스템 또는 기기 상태 업데이트. 시스템용으로 예약됨</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SERVICE">CATEGORY_SERVICE</a></code></p>
+</td>
+ <td>
+<p>실행 중인 백그라운드 서비스에 대한 표시</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_RECOMMENDATION">CATEGORY_RECOMMENDATION</a></code></p>
+</td>
+ <td>
+<p>한 가지 특정 항목에 대한 구체적이고 시기적절한 권장 사항. 예를 들어, 뉴스
+앱이 사용자가 다음으로 읽기 원할 것이라고 생각하는 뉴스를
+권하고자 하는 경우</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_STATUS">CATEGORY_STATUS</a></code></p>
+</td>
+ <td>
+<p>기기 또는 상황별 상태에 대한 지속적인 정보</p>
+</td>
+ </tr>
+</table>
+
+<h3 id="summarize_your_notifications">알림 요약하기</h3>
+
+<p>특정 유형의 알림이 이미 보류 중일 때 앱에서 같은 유형의 새
+알림을 보내려고 하는 경우, 이 앱에 대해 두 알림을 하나의 요약 알림으로 결합합니다. 새로운 개체는
+생성하지 않아야 합니다.</p>
+
+<p>요약 알림은 사용자가 특정 종류의 알림이
+몇 개나 보류 중인지
+파악할 수 있도록 간단한 개요를 표시합니다.</p>
+
+<div class="col-6">
+
+<p><strong>잘못된 사용</strong></p>
+ <img src="{@docRoot}images/android-5.0/notifications/Summarise_Dont.png" alt="" width="311px" />
+</div>
+
+<div>
+<p><strong>올바른 사용</strong></p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/Summarise_Do.png" alt="" width="311px" />
+</div>
+
+<p style="clear:left; padding-top:30px; padding-bottom:20px">확장된 다이제스트 레이아웃을 사용하여
+요약에 포함된 각각의 알림에 대한
+더 자세한 정보를 제공할 수 있습니다. 이 방식을 통해 사용자는
+어떠한 알림이 보류 중이고,
+관련된 앱에서
+상세 정보를 읽고 싶을 정도로 알림이 흥미로운지를
+판단할 수 있습니다.</p>
+<div class="col-6">
+ <img src="{@docRoot}images/android-5.0/notifications/Stack.png" style="margin-bottom:20px" alt="" width="311px" />
+ <p class="img-caption">
+ 확장된 알림 및 축소된 요약 알림(<code>InboxStyle</code> 사용)
+ </p>
+</div>
+
+<h3 style="clear:both" id="make_notifications_optional">알림을
+선택 항목으로 만들기</h3>
+
+<p>사용자는 항상 알림을 통제할 수 있어야 합니다. 애플리케이션 설정에 알림 설정 항목을 추가하여
+사용자가 앱의
+알림을
+해제하거나 경고 속성(예: 경고음 및 진동 사용
+여부)을 변경할 수 있도록 허용합니다.</p>
+
+<h3 id="use_distinct_icons">뚜렷한 아이콘 사용</h3>
+<p>알림 영역을 봄으로써 사용자는 현재
+어떠한 종류의
+알림이 보류 중인지 파악할 수 있어야 합니다.</p>
+
+<div class="figure">
+ <img src="{@docRoot}images/android-5.0/notifications/ProductIcons.png" alt="" width="420" />
+</div>
+
+ <div><p><strong>올바른 사용</strong></p>
+ <p>Android 앱이 이미 제공하는 알림 아이콘을 살펴본 후 본인의 앱에서
+뚜렷히 나타날 수 있는
+알림 아이콘을 만듭니다.</p>
+
+ <p><strong>올바른 사용</strong></p>
+ <p>작은 아이콘에
+적절한 <a href="/design/style/iconography.html#notification">알림 아이콘 스타일</a>을 사용하며, 작업
+아이콘에는 머티어리얼 라이트
+<a href="/design/style/iconography.html#action-bar">작업 모음 아이콘
+스타일</a>을 사용합니다.</p>
+<p ><strong>올바른 사용</strong></p>
+<p >아이콘은 시각적으로 단순하게 유지하고,
+알아차리기 힘들 정도로 과도하게 세부적인 디자인은 피합니다.</p>
+
+ <div><p><strong>잘못된 사용</strong></p>
+ <p>작은
+아이콘 및 작업
+아이콘에 알파(어둡게 설정 또는 페이드 효과)를 추가합니다. 아이콘의 가장자리를 안티-앨리어싱할 수는 있지만, Android가 이러한
+아이콘을 마스크(즉,
+알파 채널만 사용됨)로 사용하기 때문에 일반적으로 이미지는 최대 수준의
+불투명도로 그려집니다.</p>
+
+</div>
+<p style="clear:both"><strong>잘못된 사용</strong></p>
+
+<p>다른 앱과의 차별화를 위해 색상을 사용합니다. 알림 아이콘은 투명한 배경 이미지에 흰색 아이콘이어야만
+합니다.</p>
+
+
+<h3 id="pulse_the_notification_led_appropriately">알림 LED를
+적절하게 사용하기</h3>
+
+<p>많은 Android 기기에는 알림 LED가 내장되어 있으며, 이러한 알림 LED는 화면이 꺼져 있을 때
+사용자에게
+이벤트에 대해 알리기 위해 사용됩니다. 우선 순위가 <code>MAX</code>,
+<code>HIGH</code> 또는 <code>DEFAULT</code>인 알림의 경우
+LED가 켜지며, 낮은 우선 순위(<code>LOW</code> 및
+<code>MIN</code>)의 알림의 경우 LED가 켜지지 않습니다.</p>
+
+<p>알림과 관련하여 사용자는 LED도 제어할 수 있어야 합니다.
+DEFAULT_LIGHTS를 사용하는 경우
+LED는 흰색으로 켜집니다. 사용자가
+명시적으로 지정한 경우 외에는 다른 알림
+색상을 사용할 수 없습니다.</p>
+
+<h2 id="building_notifications_that_users_care_about">사용자가 관심을 가질 만한
+알림 만들기</h2>
+
+<p>사용자의 사랑을 받는 앱을 만들기 위해서는
+알림을 신중하게 디자인해야 합니다.
+알림은 앱의 목소리를 대변하며, 앱의
+개성에 큰 영향을 미칩니다. 원하지 않거나
+중요하지 않은 알림은 사용자를 성가시게 하거나 앱에서
+많은 신경을
+쓰게 하는 것에 대해 짜증이 나게 합니다. 따라서 알림을 사용할 때는 현명하게 판단해야 합니다.</p>
+
+<h3 id="when_to_display_a_notification">알림을 표시해야 하는 경우</h3>
+
+<p>사람들이 즐겨 사용하는 애플리케이션을 만들려면 사용자의
+주의와 집중을 흐트러뜨리지 않고 보호해야 하는 리소스임을
+인지하는 것이 중요합니다. Android의
+알림 시스템은 알림이 사용자의 주의를 최대한 방해하지 않도록
+디자인되었습니다.
+하지만
+알림이
+사용자의 태스크 흐름을 방해한다는 사실을 계속해서 인지해야 합니다.
+알림을 계획할 때 알림이 사용자의 작업을 중단할 만큼
+중요한지 곰곰히 생각해 보시기 바랍니다. 잘 모르겠는 경우, 사용자가 앱의 알림 설정을 사용하여 알림에 대한 수신 동의를
+선택할 수 있도록 허용하거나 알림 우선 순위 플래그를 <code>LOW</code> 또는 <code>MIN</code>으로
+조정하여 사용자 작업을
+방해하지
+않도록 합니다.</p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/TimeSensitive.png" alt="" width="311px" />
+ <p style="margin-top:10px" class="img-caption">
+ 시간에 민감한 알림의 예
+ </p>
+
+<p>일반적으로 잘 만들어진 앱은 사용자의 요청이 있을 때에만 정보를 알리고
+요청하지 않은 알림은 꼭 필요한 경우에만 표시하도록 합니다.</p>
+
+<p>알림은 <strong>시간에 민감한 이벤트</strong>에 주로 사용하며, 특히
+이러한 동기적 이벤트에 <strong>다른 사람이 관련된 경우</strong>에 사용합니다. 예를
+들어 수신되는 채팅 메시지는
+실시간으로 진행되는 동기적 대화 형식이며, 이때 다른 사람은
+적극적으로 응답을 기다립니다. 캘린더 이벤트는 언제
+알림을 사용하고
+사용자의 주의를 끌어야 하는지에 대해 알 수 있는 또 다른 좋은 예입니다. 왜냐하면 이는 임박한 이벤트이며, 캘린더 이벤트에는 종종 다른 사람이
+관련되기 때문입니다.</p>
+
+<h3 style="clear:both" id="when_not_to_display_a_notification">알림을
+표시하지 않아야 하는 경우</h3>
+
+<div class="figure" style="margin-top:60px">
+ <img src="{@docRoot}images/android-5.0/notifications/AntiSample1.png" alt="" width="311px" />
+</div>
+
+<p>다른 대부분의 경우 알림은 적합하지 않습니다.</p>
+
+<ul>
+ <li> 사용자와
+직접 관련이 없는 정보나 시간에 민감하지 않은
+정보는 알리지 않도록 합니다. 예를 들어 소셜 네트워크를 통한 비동기적이며
+대상이 불특정한 업데이트는
+일반적으로 실시간으로
+사용자를 방해할 수 없습니다. 그러한 업데이트를 원하는 사용자의
+경우에는 사전에 수신 동의를 설정할 수 있게 하면 됩니다.</li>
+ <li> 관련된 새 정보가 현재
+화면에 표시된 경우에는 알림을 생성하지 않아야 합니다. 대신 애플리케이션 UI를
+사용하여 컨텍스트 내에 새로운 정보가 있음을 사용자에게
+직접 알립니다.
+ 예를 들어 채팅 애플리케이션은
+사용자가 다른 사용자와 대화 중일 때는 시스템 알림을 생성하지 않아야 합니다.</li>
+ <li> 정보 저장
+또는 동기화, 애플리케이션 업데이트와 같은 낮은 수준의 기술 정보의 경우 사용자가 개입하지
+않아도 앱이나 시스템에서 스스로 알아서 처리할 수 있다면 사용자를 방해하지 않도록 합니다.</li>
+ <li> 사용자가 아무런 조치를
+취하지 않아도 애플리케이션 스스로 오류를 복구할
+수 있는 경우, 이러한 오류에 대해 사용자에게 알리지 않도록 합니다.</li>
+ <li> 알리는 내용은 없고
+단순히 앱을
+홍보하는 알림은 만들지 않습니다. 알림은 유용하고, 시기적절하며 새로운 정보를 제공해야 하며, 단지 앱 출시를 위한 용도로는
+사용하지
+않습니다.</li>
+ <li> 단지
+사용자에게 브랜드를 알리기 위한 불필요한 알림은 만들지 않도록 합니다.
+ 그러한 알림은 사용자를 짜증 나게 만들어 앱에 대한 관심을 멀어지게 합니다. 소량의
+업데이트된 정보를 제공하면서 사용자가 지속적으로
+앱에 관심을
+갖게 만드는 최고의
+방법은
+홈 화면에 추가할 수 있는 위젯을 개발하는 것입니다.</li>
+</ul>
+
+<h2 style="clear:left" id="interacting_with_notifications">알림과
+상호 작용하기</h2>
+
+<p>알림은 상태 표시줄에 아이콘으로 표시되며,
+알림 창을 열어서
+확인할 수 있습니다.</p>
+
+<p>알림을 터치하면 관련 앱이 열리고 알림에
+해당되는 세부 내용이 표시됩니다. 알림을 왼쪽이나 오른쪽으로
+스와이프하면 알림 창에서 제거됩니다.</p>
+
+<h3 id="ongoing_notifications">지속적인 알림</h3>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/MusicPlayback.png" alt="" width="311px" />
+ <p class="img-caption">
+ 음악 재생으로 인한 지속적인 알림
+ </p>
+</div>
+<p>지속적인 알림은
+백그라운드에서 진행 중인 프로세스에 대해 사용자에게 알립니다.
+예를 들어 음악 플레이어는 사용자가 재생을 멈출 때까지
+알림 시스템 내에 현재 재생 중인 트랙을
+계속 표시합니다. 또한 지속적인 알림은 파일을 다운로드하거나 비디오를 인코딩하는 등의 장기 태스크에 대한
+피드백을 사용자에게
+표시할 수도 있습니다. 지속적인 알림은 사용자가 알림 창에서 직접
+제거할 수 없습니다.</p>
+
+<h3 id="ongoing_notifications">미디어 재생</h3>
+<p>Android 5.0에서는 잠금 화면에 사용이 중단된
+{@link android.media.RemoteControlClient} 클래스에 대한 전송 제어가 표시되지 않습니다. 하지만 알림은 <em>표시되며</em>, 각
+앱의 재생 알림이 현재 사용자가 잠금 상태에서 재생을 제어하는 기본
+방법입니다. 이 동작은 화면의 잠금 여부와 상관없이 사용자에게
+일관된 환경을 제공하면서, 어떠한 버튼을
+어떻게 표시할지에 대해 앱이 더 세부적으로 제어할 수 있도록
+지원합니다.</p>
+
+<h3 style="clear:both"
+id="dialogs_and_toasts_are_for_feedback_not_notification">대화 상자
+및 알림 메시지</h3>
+
+<p>현재
+화면에 표시되어 있는 경우가 아니라면 앱은 대화 상자나 알림 메시지를 생성해서는 안 됩니다. 대화 상자나 알림 메시지는
+앱 내에서
+사용자가 어떠한 행동을 취했을 때 이에 대한 즉각적인 응답으로만 표시되어야 합니다.
+대화 상자 및 알림 메시지 사용에 대한 자세한 지침은
+<a href="/design/patterns/confirming-acknowledging.html">확인 및 승인하기</a>를 참조하세요.</p>
+
+<h3>순위 및 순서</h3>
+
+<p>알림은 뉴스이므로, 기본적으로 발생한 순서의 역순으로
+표시되며, 특히
+앱에서 명시된 알림
+<a href="#correctly_set_and_manage_notification_priority">우선 순위</a>에 따라 순서가 결정됩니다.</p>
+
+<p>알림은 잠금 화면에서 중요한 부분이며, 기기의 화면이 켜질
+때마다
+표시됩니다. 잠금 화면의 공간은 협소하기 때문에 가장 긴급하고 관련 있는 알림을 식별하는 것이
+가장
+중요합니다. 이러한
+이유 때문에 Android에는 다음을 고려한
+더욱 정교한 정렬 알고리즘이 있습니다.</p>
+
+<ul>
+ <li> 타임스탬프 및 애플리케이션에 명시된 우선 순위.</li>
+ <li> 알림이 최근에 소리 또는
+진동으로 사용자를 방해했는지에 대한 여부. (즉,
+휴대폰에서 방금 소리가 났을 때 사용자가 "방금 무슨
+일이 있었지?"에 대해 알고 싶어하는 경우 잠금 화면을
+보면 한 눈에 알 수 있어야 합니다.)</li>
+ <li> {@link android.app.Notification#EXTRA_PEOPLE}을 사용하여 알림에 첨부된 사람,
+그리고 특히 즐겨찾기에 추가된 연락처인지에 대한 여부.</li>
+</ul>
+
+<p>이러한 정렬 알고리즘을 잘 이용하기 위해서는 목록의 특정 부분에 초점을 두기 보다는 생성하고자
+하는 사용자
+환경에 초점을 둡니다.</p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/AntiSample3.png" alt="" width="700px" />
+
+ <p class="img-caption" style="margin-top:10px">Gmail 알림은
+기본 우선 순위이기 때문에
+보통은 행아웃과 같은 인스턴트 메시징 앱에서 온 메시지보다 하위에 정렬됩니다. 하지만
+새 메시지가 들어오면
+일시적으로 순위가 올라갑니다.
+ </p>
+
+
+<h3>잠금 화면</h3>
+
+<p>알림은 잠금 화면에 표시되기 때문에 사용자의 개인 정보 보호가
+특히
+중요하게 고려해야 할 사항입니다. 알림은 종종 민감한 정보를 포함하기 때문에, 아무나
+기기의 화면을 켰을 때 볼 수 있게 할 필요는
+없습니다.</p>
+
+<ul>
+ <li> 보안 잠금 화면(PIN, 패턴 또는 암호)이 있는 기기의 인터페이스에는
+공개 및 비공개 부분이 있습니다. 공개 인터페이스는 보안 잠금 화면에 표시될 수 있기 때문에
+누구나 볼 수 있습니다. 비공개 인터페이스는 잠금 화면 뒤에 있기 때문에
+기기의 잠금 화면을 푼 사람만 볼 수 있습니다.</li>
+</ul>
+
+<h3>보안 잠금 화면에 표시된 정보에 대한 사용자 제어</h3>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/LockScreen@2x.png" srcset="{@docRoot}images/android-5.0/notifications/LockScreen.png 1x" alt="" width="311px" />
+ <p class="img-caption">
+ 사용자가 기기의 잠금을 푼 후 보이는 콘텐츠와 함께 잠금 화면에 표시된 알림
+ </p>
+</div>
+
+<p>보안 잠금 화면을 설정할 때 사용자는
+민감한 세부 정보를 보안 잠금 화면에서 숨기도록 선택할 수 있습니다. 이러한 경우 시스템 UI는 알림의 <em>정보 공개 수준</em>을
+고려하여
+안전하게 표시할 수 있는 정보를 파악합니다.</p>
+<p> 정보 공개 수준을 제어하려면
+<code><a
+href="/reference/android/app/Notification.Builder.html#setVisibility(int)">Notification.Builder.setVisibility()</a></code>를 호출한 후
+다음 값 중 하나를 지정합니다.</p>
+
+<ul>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_PUBLIC">VISIBILITY_PUBLIC</a></code>. 알림의 전체 내용을
+표시합니다.
+ 정보 공개 수준을 지정하지 않을 경우 시스템 기본값입니다.</li>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_PRIVATE">VISIBILITY_PRIVATE</a></code>.
+잠금 화면에 알림의
+아이콘과 알림을 게시한 앱의 이름을 포함하여 해당 알림의 존재에 대한 기본 정보를 표시합니다. 알림의 나머지 세부 사항은 표시되지 않습니다.
+다음과 같은 몇 가지 유용한 사항을 염두해야 합니다.
+ <ul>
+ <li> 시스템이 보안 잠금 화면에 다른 공개 버전의 알림을
+표시하도록 제공하려는 경우, <code><a
+href="/reference/android/app/Notification.html#publicVersion">Notification.publicVersion</a></code>
+필드에 대체
+알림 개체를 제공해야 합니다.
+ <li> 이렇게 설정하면 앱에서 여전히 유용하지만 개인 정보를 노출하지 않는 편집된 버전의
+내용을 생성할 수 있습니다. 예를 들어, 알림에 SMS 텍스트, 발신자 이름 및 연락처 아이콘을 포함하는
+SMS 앱이 있다고 가정합니다.
+이 알림은 <code>VISIBILITY_PRIVATE</code>여야 하지만, <code>publicVersion</code>은 다른 식별
+정보 없이 "3개의 새 메시지"와 같이 여전히 유용한 정보를
+포함할 수 있습니다.
+ </ul>
+ </li>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_SECRET">Notification.VISIBILITY_SECRET</a></code>. 최소한의 정보만 표시하며, 알림의 아이콘마저
+표시하지 않습니다.</li>
+</ul>
+<h2 style="clear:both" id="notifications_on_android_wear">Android Wear에
+표시되는 알림</h2>
+
+<p>Android Wear에 표시되는 알림과 해당 <em>작업</em>은 기본적으로 Wear 기기에 연결되어 있습니다.
+개발자는 어떠한 알림을
+휴대폰에서 워치로,
+그리고 그 반대로 연결할지 제어할 수 있습니다. 또한 개발자는 어떠한 작업을 연결할지도 제어할 수 있습니다. 앱이
+단일 탭으로 실행할 수 없는
+작업을 포함하는 경우, 이러한 작업을
+Wear
+알림에 표시되지 않도록 숨기거나 Wear 앱에 연결하여 사용자가
+워치에서 작업을
+끝낼 수 있도록 합니다.</p>
+
+<h4>알림과 작업 연결하기</h4>
+
+<p>휴대폰과 같이 연결된 기기는 알림을 Wear 기기에 연결하여 해당 기기에서
+알림이 표시될 수 있게 합니다. 마찬가지로 작업도 연결할 수 있기 때문에 사용자는 Wear 기기에서
+알림을 바로 처리할 수 있습니다.</p>
+
+<p><strong>연결해야 할 사항</strong></p>
+
+<ul>
+ <li> 새 인스턴트 메시지</li>
+ <li> +1, Like, Heart와 같은 단일 탭 작업</li>
+</ul>
+
+<img src="{@docRoot}images/android-5.0/notifications/WearBasic.png" width="156px" height="156px" alt="" />
+
+<p><strong>연결하지 않아야 할 사항</strong></p>
+
+<ul>
+ <li> 새로 도착한 팟캐스트의 알림</li>
+ <li> 워치에서 수행할 수 없는 기능에 매핑되는 작업</li>
+</ul>
+
+
+
+<p><h4>Wear에 대해서만 정의할 수 있는 고유한 작업</h4></p>
+
+<p>Wear에서만 수행할 수 있는 작업이 몇 가지 있으며, 이러한 작업은 다음과 같습니다.</p>
+
+<ul>
+ <li> "금방 올게"와 같은 미리 준비된 대답으로 구성된 빠른 목록</li>
+ <li> 휴대폰에서 열기</li>
+ <li> 음성 입력 화면을 불러오는 "댓글 달기" 또는 "응답" 작업</li>
+ <li> Wear에 특화된 앱을 실행하는 작업</li>
+</ul>
+
+<img src="{@docRoot}images/android-5.0/notifications/ReplyAction.png" width="156px" height="156px" alt="" />
diff --git a/docs/html-intl/intl/ko/preview/api-overview.jd b/docs/html-intl/intl/ko/preview/api-overview.jd
new file mode 100644
index 0000000..aac9a44
--- /dev/null
+++ b/docs/html-intl/intl/ko/preview/api-overview.jd
@@ -0,0 +1,521 @@
+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/behavior-changes.jd b/docs/html-intl/intl/ko/preview/behavior-changes.jd
new file mode 100644
index 0000000..fa95070
--- /dev/null
+++ b/docs/html-intl/intl/ko/preview/behavior-changes.jd
@@ -0,0 +1,402 @@
+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/features/runtime-permissions.jd b/docs/html-intl/intl/ko/preview/features/runtime-permissions.jd
new file mode 100644
index 0000000..20c5232
--- /dev/null
+++ b/docs/html-intl/intl/ko/preview/features/runtime-permissions.jd
@@ -0,0 +1,794 @@
+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/overview.jd b/docs/html-intl/intl/ko/preview/overview.jd
new file mode 100644
index 0000000..d325725
--- /dev/null
+++ b/docs/html-intl/intl/ko/preview/overview.jd
@@ -0,0 +1,362 @@
+page.title=프로그램 개요
+page.metaDescription=Android M 개발자 미리 보기를 시작하신 여러분, 환영합니다. 이 프로그램은 Android의 다음 버전에 대해 앱을 테스트하고 최적화하는 데 필요한 모든 것을 제공해 드립니다.
+page.image=images/cards/card-preview_16-9_2x.png
+page.tags="preview", "developer", "android"
+
+@jd:body
+
+<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/training/basics/activity-lifecycle/index.jd b/docs/html-intl/intl/ko/training/basics/activity-lifecycle/index.jd
new file mode 100644
index 0000000..e66e8d1
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/basics/activity-lifecycle/index.jd
@@ -0,0 +1,72 @@
+page.title=액티비티 수명 주기 관리하기
+page.tags=activity lifecycle
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+
+<h2>종속관계 및 전제조건</h2>
+<ul>
+ <li>Android 프로젝트를 생성하는 방법(<a href="{@docRoot}training/basics/firstapp/creating-project.html">Android
+프로젝트 생성</a> 참조)</li>
+</ul>
+
+
+<h2>필독 항목</h2>
+<ul>
+ <li><a href="{@docRoot}guide/components/activities.html">액티비티</a></li>
+</ul>
+
+
+<h2>실습하기</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">데모 다운로드</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>사용자가 앱을 탐색하고, 앱에서 나가고, 앱으로 다시 돌아가면, 앱의
+{@link android.app.Activity} 인스턴스는
+수명 주기 안에서 서로 다른 상태 간에 전환됩니다. 예를 들어
+액티비티가 처음 시작되는 경우, 시스템의 전면에 표시되어 사용자의
+포커스를 받습니다. 이 과정에서 Android 시스템은 사용자 인터페이스 및 다른 구성요소에 설정된
+액티비티에 대해 일련의 수명 주기 메서드를 호출합니다. 사용자가 다른 액티비티를 시작하거나 다른 앱으로 전환하는
+작업을 수행하면, 백그라운드(액티비티가 더
+이상 보이지 않지만 인스턴스와 해당 상태는 그대로 유지되는 상태)로 전환되면서 시스템은 액티비티에 대해 또 다른
+수명 주기 메서드 세트를 호출합니다.</p>
+
+<p>사용자가 액티비티를 떠났다가 다시 돌아왔을 때
+액티비티가 어떤 식으로 동작할지에 대해 수명 주기 콜백 메서드 내에 선언할 수 있습니다. 예를 들어 스트리밍 비디오 플레이어를 구축하는 경우,
+사용자가 다른
+앱으로 전환할 때 비디오를 일시정지하고 네트워크 연결을 종료할 수 있습니다. 사용자가 돌아오면, 네트워크를 다시 연결하고 사용자가 일시정지한 지점에서
+비디오를 다시 시작할 수 있게 할 수 있습니다.</p>
+
+<p>이 클래스에서는 각각의 {@link
+android.app.Activity} 인스턴스가 수신하는 중요한 수명 주기 콜백 메서드를 설명합니다. 또한 이러한 콜백 메서드를 사용하여 액티비티가
+사용자가 원하는 작업을 하고, 액티비티가 필요로 하지 않을 때 시스템 리소스 소비를 방지하는 방법에 대해서도 설명합니다.</p>
+
+<h2>과정</h2>
+
+<dl>
+ <dt><b><a href="starting.html">액티비티 시작하기</a></b></dt>
+ <dd>액티비티 수명 주기의 기본사항, 사용자가 앱을 시작하는 방법, 그리고 기본 액티비티 생성 작업을 수행하는
+방법에 대해 설명합니다.</dd>
+ <dt><b><a href="pausing.html">액티비티 일시정지 및 재개하기</a></b></dt>
+ <dd>액티비티가 일시정지(부분적으로 가려져 있음)되었다가 재개되는 경우 어떤 동작이 발생하는지, 그리고 이러한 상태 전환 과정에서 수행해야 하는
+작업은 무엇인지 설명합니다.</dd>
+ <dt><b><a href="stopping.html">액티비티 정지 및 재시작하기</a></b></dt>
+ <dd>사용자가 액티비티를 완전히 떠났다가 돌아왔을 때 어떤 동작이 발생하는지 설명합니다.</dd>
+ <dt><b><a href="recreating.html">액티비티 재생성하기</a></b></dt>
+ <dd>액티비티가 소멸되면 어떤 동작이 발생하는지, 그리고 필요 시 액티비티
+상태를 재구축하는 방법에 대해 설명합니다.</dd>
+</dl>
+
diff --git a/docs/html-intl/intl/ko/training/basics/activity-lifecycle/pausing.jd b/docs/html-intl/intl/ko/training/basics/activity-lifecycle/pausing.jd
new file mode 100644
index 0000000..b0497cd
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/basics/activity-lifecycle/pausing.jd
@@ -0,0 +1,147 @@
+page.title=액티비티 일시정지 및 재개하기
+page.tags=activity lifecycle
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>이 과정에서 다루는 내용</h2>
+ <ol>
+ <li><a href="#Pause">액티비티 일지정지하기</a></li>
+ <li><a href="#Resume">액티비티 재개하기</a></li>
+ </ol>
+
+ <h2>필독 항목</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">액티비티</a>
+ </li>
+ </ul>
+
+<h2>실습하기</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">데모 다운로드</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>일반적인 앱 사용 중에 가끔 다른
+비주얼 구성요소로 인해 전면의 액티비티가 <em>일시정지</em>되는 경우가 있습니다. 예를 들어, 대화 상자 스타일과 같은 반투명
+액티비티가 열리면, 그 이전 액티비티는 일시정지됩니다. 액티비티가
+부분적으로 보이지만 현재 포커스 내에 있지 않는 한 일시정지된 상태로 유지됩니다.</p>
+
+<p>하지만 액티비티가 보이지 않고 완전히 가려지면, <em>정지</em> 상태가 됩니다(이에 대해서는
+다음 과정에서 설명함).</p>
+
+<p>액티비티가 일시정지 상태로 전환되면 시스템은 {@link android.app.Activity}에 대해 {@link
+android.app.Activity#onPause onPause()} 메서드를 호출합니다. 이를 통해
+비디오와 같이 일시정지되어 있는 동안에는 진행되어서는 안 되는 지속적인 작업을 정지하거나, 사용자가 앱에서 떠나더라도 영구 저장되어야 하는 정보를
+유지할 수 있습니다. 사용자가
+일시정지 상태에서 액티비티로 돌아오는 경우, 시스템은 액티비티를 재개하고 {@link android.app.Activity#onResume onResume()} 메서드를
+호출합니다.</p>
+
+<p class="note"><strong>참고:</strong> 액티비티가 {@link
+android.app.Activity#onPause()}에 대한 호출을 수신하는 경우, 이는 액티비티가
+잠시 일시정지되는 것이며, 사용자가 이 액티비티로 포커스를 다시 돌릴 수 있음을 나타냅니다. 하지만 이는 일반적으로 사용자가 액티비티를 떠남을 나타내는
+첫 번째 표시입니다.</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-paused.png" />
+<p class="img-caption"><strong>그림 1.</strong> 액티비티를
+반투명 액티비티가 가릴 경우, 시스템은 {@link android.app.Activity#onPause onPause()}를 호출하고 액티비티는 일시정지된 상태로
+대기하게 됩니다(1). 사용자가 여전히 일시정지된 상태의 액티비티로 돌아오는 경우,
+시스템은 {@link android.app.Activity#onResume onResume()}을 호출합니다(2).</p>
+
+
+<h2 id="Pause">액티비티 일지정지하기</h2>
+
+<p>시스템이 액티비티에 대해 {@link android.app.Activity#onPause()}를 호출하면, 이는
+엄밀해 말해 액티비티가 여전히 부분적으로 보일 수 있음을 의미하지만,
+대개의 경우 사용자가 액티비티를 떠나 곧 정지 상태로 전환될 것임을 나타냅니다. 일반적으로 다음 작업을 수행할 때
+{@link android.app.Activity#onPause()} 콜백을 사용해야 합니다.</p>
+
+<ul>
+ <li>애니메이션 또는 CPU 소비를 야기할 수 있는 기타 지속적인 작업 정지</li>
+ <li>저장되지 않은 변경 내용 커밋. 단, 사용자가 나갈 때
+이러한 변경 내용이 영구적으로 저장되기를 기대하는 경우에 한합니다(예: 이메일 임시저장).</li>
+ <li>브로드캐스트 리시버와 같은 시스템 리소스, GPS와
+같은 센서에 대한 핸들 또는 액티비티가 일지정지된 동안 배터리 수명에 영향을 미칠 수 있으며 사용자가
+필요로 하지 않는 모든 리소스 해제</li>
+</ul>
+
+<p>예를 들어 애플리케이션이 {@link android.hardware.Camera}를 사용하는 경우
+{@link android.app.Activity#onPause()} 메서드는 이를 해제할 수 있는 좋은 위치입니다.</p>
+
+<pre>
+&#64;Override
+public void onPause() {
+ super.onPause(); // Always call the superclass method first
+
+ // Release the Camera because we don't need it when paused
+ // and other activities might need to use it.
+ if (mCamera != null) {
+ mCamera.release()
+ mCamera = null;
+ }
+}
+</pre>
+
+<p>일반적으로 폼에 입력된 개인 정보와 같은
+사용자의 변경 내용을 {@link android.app.Activity#onPause()}를 사용하여 영구 저장소에 저장하면 <strong>안 됩니다</strong>. 이메일
+임시보관과 같이 사용자가 자동저장을 원할 것이란 확신이 있을 경우에만 {@link android.app.Activity#onPause()}
+내에서 사용자의 변경 내용을 영구 저장소에 유지해야 합니다.
+하지만 데이터베이스에 쓰기와 같이 CPU를 많이 소모하는 작업은 {@link
+android.app.Activity#onPause()} 중에는 수행하지 않아야 합니다. 그 이유는 이로 인해 다음 액티비티로 넘어가는 시각적
+전환이 느려질 수 있기 때문입니다(그 대신, 로드가 많은 셧다운 작업은 {@link android.app.Activity#onStop onStop()}
+중에 수행해야 함).</p>
+
+<p>액티비티가 실제로 정지된 경우 사용자가 다음
+대상으로 신속하게 전환할 수 있도록 {@link android.app.Activity#onPause
+onPause()} 메서드 내에서 수행되는 작업의 양을 비교적 단순하게 유지해야 합니다.</p>
+
+<p class="note"><strong>참고:</strong> 액티비티가 일시정지되면 {@link
+android.app.Activity} 인스턴스는 메모리에 계속 유지되며, 액티비티가 재개되면 다시 호출됩니다.
+최상위 상태가 재개됨 상태인 콜백 메서드 중에
+생성된 구성요소는 다시 초기화할 필요가 없습니다.</p>
+
+
+
+<h2 id="Resume">액티비티 재개하기</h2>
+
+<p>사용자가 일시정지됨 상태에서 액티비티를 재개하면, 시스템은 {@link
+android.app.Activity#onResume()} 메서드를 호출합니다.</p>
+
+<p>액티비티가 처음 생성되는 경우를
+포함하여 액티비티가 전면에 표시될 때마다 시스템이 이 메서드를 호출한다는 것을 유의해야 합니다. 이와 같이, {@link
+android.app.Activity#onResume()}을 구현하여 {@link
+android.app.Activity#onPause()} 중에 해제하는 구성요소를 초기화하고, 액티비티가
+재개됨 상태로 전환될 때마다 필요한 다른 초기화 작업도 수행해야 합니다(예: 애니메이션 시작 및 액티비티가 사용자 포커스를 받을 때에만
+사용되는 구성 요소 초기화).</p>
+
+<p>다음 {@link android.app.Activity#onResume()} 예제는 위에 표시된
+{@link android.app.Activity#onPause()} 예제와 대응관계에 있습니다. 따라서 이 예제에서는 액티비티가 일시정지될 때
+해제되는 카메라를 초기화합니다.</p>
+
+<pre>
+&#64;Override
+public void onResume() {
+ super.onResume(); // Always call the superclass method first
+
+ // Get the Camera instance as the activity achieves full user focus
+ if (mCamera == null) {
+ initializeCamera(); // Local method to handle camera init
+ }
+}
+</pre>
+
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/ko/training/basics/activity-lifecycle/recreating.jd b/docs/html-intl/intl/ko/training/basics/activity-lifecycle/recreating.jd
new file mode 100644
index 0000000..79fb92b
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/basics/activity-lifecycle/recreating.jd
@@ -0,0 +1,178 @@
+page.title=액티비티 재생성하기
+page.tags=activity lifecycle
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>이 과정에서 다루는 내용</h2>
+ <ol>
+ <li><a href="#SaveState">액티비티 상태 저장하기</a></li>
+ <li><a href="#RestoreState">액티비티 상태 복원하기</a></li>
+ </ol>
+
+ <h2>필독 항목</h2>
+ <ul>
+ <li><a href="{@docRoot}training/basics/supporting-devices/screens.html">다양한
+화면 지원</a></li>
+ <li><a href="{@docRoot}guide/topics/resources/runtime-changes.html">런타임 변경 처리하기</a></li>
+ <li><a href="{@docRoot}guide/components/activities.html">액티비티</a>
+ </li>
+ </ul>
+
+ </div>
+</div>
+
+<p>정상적인 앱 동작으로 인해 액티비티가 소멸되는 몇 가지 시나리오가 있습니다.
+예를 들어 사용자가 <em>뒤로</em> 버튼을 누르거나 액티비티가 {@link android.app.Activity#finish()}를 호출하여
+자체적인 소멸 신호를 보내는 경우입니다. 또한 액티비티가
+현재 정지되어 있고 장시간 사용되지 않거나, 전면에 있는 액티비티가 더 많은
+리소스를 필요로 하여 시스템이 백그라운드 프로세스를 종료해서 메모리를 회수해야 하는 경우에도 시스템이 액티비티를 소멸시킬 수 있습니다.</p>
+
+<p>사용자가 <em>뒤로</em> 버튼을 누르거나 액티비티가
+스스로 종료되어 소멸된 경우, {@link android.app.Activity} 인스턴스에 대한 시스템의 개념은 완전히 사라지게 됩니다. 왜냐하면
+동작이 액티비티가 더 이상 필요치 않다는 것을 나타내기 때문입니다. 하지만 시스템이 정상적인 앱 동작이 아닌 시스템 제약 조건으로 인해
+액티비티를 소멸한 경우, 실제
+{@link android.app.Activity} 인스턴스는 사라지지만 시스템은 그것이 존재하고 있었음을 기억합니다. 예를 들어
+사용자가 다시 해당 액티비티를 탐색하면, 시스템은 소멸된 액티비티의 상태를 설명하는
+저장된 데이터 세트를 사용하여 액티비티의 새 인스턴스를 생성합니다. 시스템이
+이전 상태를 복원하기 위해 사용하는 저장된 데이터를 "인스턴스 상태"라고 하며, 이는 {@link android.os.Bundle} 개체에 저장된
+키-값 쌍의 컬렉션입니다.</p>
+
+<p class="caution"><strong>주의:</strong> 사용자가 화면을 회전할 때마다
+액티비티가 소멸되고 재생성됩니다. 화면 방향이 바뀌면 시스템은
+전면에 있는 액티비티를 소멸하고 재생성합니다. 그 이유는 화면 구성이 바뀌었으며, 액티비티가 레이아웃과 같은 대체 리소스를
+로딩해야 할 수 있기 때문입니다.</p>
+
+<p>기본적으로 시스템은 {@link android.os.Bundle} 인스턴스 상태를 사용하여 액티비티 레이아웃의 각 {@link android.view.View} 개체에 대한
+정보를 저장합니다(예: {@link android.widget.EditText} 개체에
+입력된 텍스트 값 등). 따라서 액티비티 인스턴스가 소멸되고
+재생성된 경우, 레이아웃의 상태는
+별도의 코드 요청 없이 이전 상태로 복원됩니다. 하지만
+액티비티에서 사용자 진행 상태를
+추적하는 멤버 변수처럼 액티비티에 복원하고자 하는 상태 정보가 더 많이 있는 경우도 있습니다.</p>
+
+<p class="note"><strong>참고:</strong> Android 시스템이 액티비티에서
+보기의 상태를 복원하기 위해서는
+<a href="{@docRoot}reference/android/view/View.html#attr_android:id">{@code
+android:id}</a> 특성으로 제공되는 <strong>고유 ID가 각 보기마다 있어야 합니다</strong>.</p>
+
+<p>액티비티 상태에 대한 추가 데이터를 저장하려면
+{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} 콜백 메서드를 재정의해야 합니다.
+시스템은 사용자가 액티비티를 떠날 경우 이 메서드를 호출하며,
+액티비티가 예기치 않게 소멸될 경우 저장되는
+{@link android.os.Bundle} 개체로 전달합니다. 시스템이
+나중에 액티비티 인스턴스를 재생성해야 하는 경우, 동일한 {@link
+android.os.Bundle} 개체를 {@link android.app.Activity#onRestoreInstanceState
+onRestoreInstanceState()} 및 {@link android.app.Activity#onCreate onCreate()}
+메서드 모두에 전달합니다.</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-savestate.png" />
+<p class="img-caption"><strong>그림 2.</strong> 시스템은 액티비티 중지 작업을 시작할 때
+{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}(1)를 호출합니다.
+따라서 {@link android.app.Activity} 인스턴스가
+재생성되어야 하는 경우 저장하고자 하는 추가 상태 데이터를 지정할 수 있습니다.
+액티비티가 소멸되고 동일한 인스턴스가 재생성되어야 하는 경우, 시스템은 {@link android.app.Activity#onCreate onCreate()} 메서드(2)
+및 {@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} 메서드(3)
+모두에 (1)에서 정의된 상태
+데이터를 전달합니다.</p>
+
+
+
+<h2 id="SaveState">액티비티 상태 저장하기</h2>
+
+<p>액티비티의 정지 작업 시작 시 시스템은 {@link android.app.Activity#onSaveInstanceState
+onSaveInstanceState()}를 호출합니다. 이에 따라 액티비티는 키-값
+쌍 컬렉션과 함께 상태 정보를 저장할 수 있습니다. 메서드의 기본 구현은 {@link android.widget.EditText} 위젯 내 텍스트 또는 {@link android.widget.ListView}의 스크롤
+위치와 같은 액티비티의
+보기 계층 구조에 대한 정보를 저장합니다.</p>
+
+<p>액티비티에 대한 추가 상태 정보를 저장하려면 {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}를
+구현한 다음 {@link android.os.Bundle} 개체에
+키-값 쌍을 추가해야 합니다. 예를 들면 다음과 같습니다.</p>
+
+<pre>
+static final String STATE_SCORE = "playerScore";
+static final String STATE_LEVEL = "playerLevel";
+...
+
+&#64;Override
+public void onSaveInstanceState(Bundle savedInstanceState) {
+ // Save the user's current game state
+ savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
+ savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
+
+ // Always call the superclass so it can save the view hierarchy state
+ super.onSaveInstanceState(savedInstanceState);
+}
+</pre>
+
+<p class="caution"><strong>주의:</strong> 항상 {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()}의 슈퍼클래스 구현을 호출하여 기본 구현에서
+보기 계층 구조를 저장할 수 있도록 합니다.</p>
+
+
+
+<h2 id="RestoreState">액티비티 상태 복원하기</h2>
+
+<p>액티비티가 이전에 소멸된 후 재생성되면, 시스템이 액티비티를
+전달한 {@link android.os.Bundle}로부터 저장된
+상태를 복구할 수 있습니다. {@link android.app.Activity#onCreate onCreate()} 및 {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} 콜백 메서드 둘 다 인스턴스 상태 정보를 포함하는
+동일한 {@link android.os.Bundle}을 수신합니다.</p>
+
+<p>{@link android.app.Activity#onCreate onCreate()} 메서드는
+시스템이 액티비티의 새 인스턴스를 생성하든, 이전 인스턴스를 재생성하든 상관없이 호출되므로, 읽기를 시도하기 전에 상태 {@link android.os.Bundle}이 null인지
+반드시 확인해야 합니다. null일 경우,
+시스템은 이전에 소멸된 액티비티의 인스턴스를
+복원하지 않고 새 인스턴스를 생성합니다.</p>
+
+<p>다음은 {@link android.app.Activity#onCreate
+onCreate()}에서 몇 가지 상태 데이터를 복원하는 방법에 대한 예제입니다.</p>
+
+<pre>
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState); // Always call the superclass first
+
+ // Check whether we're recreating a previously destroyed instance
+ if (savedInstanceState != null) {
+ // Restore value of members from saved state
+ mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
+ mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
+ } else {
+ // Probably initialize members with default values for a new instance
+ }
+ ...
+}
+</pre>
+
+<p>{@link android.app.Activity#onCreate onCreate()} 중에 상태를 복원하는
+대신, 시스템이 {@link android.app.Activity#onStart()} 메서드 후에
+호출하는 {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}를 구현하도록 선택할 수 있습니다. 시스템은 복원할 저장
+상태가 있을 경우에만 {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}를 호출합니다. 따라서 {@link android.os.Bundle}이 null인지 확인할 필요가 없습니다.</p>
+
+<pre>
+public void onRestoreInstanceState(Bundle savedInstanceState) {
+ // Always call the superclass so it can restore the view hierarchy
+ super.onRestoreInstanceState(savedInstanceState);
+
+ // Restore state members from saved instance
+ mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
+ mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
+}
+</pre>
+
+<p class="caution"><strong>주의:</strong> 항상 {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()}의 슈퍼클래스 구현을 호출하여 기본 구현에서 보기 계층 구조의 상태를
+복원할 수 있도록 합니다.</p>
+
+<p>런타임에
+재시작 이벤트로 인한 액티비티 재생성과 관련한 자세한 내용은 <a href="{@docRoot}guide/topics/resources/runtime-changes.html">런타임 변경 처리하기</a>를 참조하세요.</p>
+
diff --git a/docs/html-intl/intl/ko/training/basics/activity-lifecycle/starting.jd b/docs/html-intl/intl/ko/training/basics/activity-lifecycle/starting.jd
new file mode 100644
index 0000000..71ecf06
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/basics/activity-lifecycle/starting.jd
@@ -0,0 +1,285 @@
+page.title=액티비티 시작하기
+page.tags=activity lifecycle
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>이 과정에서 다루는 내용</h2>
+<ol>
+ <li><a href="#lifecycle-states">수명 주기 콜백 이해하기</a></li>
+ <li><a href="#launching-activity">앱 시작 관리자 액티비티 지정하기</a></li>
+ <li><a href="#Create">새로운 인스턴스 생성하기</a></li>
+ <li><a href="#Destroy">액티비티 소멸하기</a></li>
+</ol>
+
+ <h2>필독 항목</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">액티비티</a></li>
+ </ul>
+
+<h2>실습하기</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">데모 다운로드</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>{@code main()} 메서드로 앱이 실행되는 다른 프로그래밍 패러다임과는 달리,
+Android 시스템은 {@link android.app.Activity} 인스턴스 수명 주기의 특정 단계에 부합하는 특정
+콜백 메서드를 호출하여 해당 인스턴스 내 코드를
+실행합니다. 액티비티를 시작하는 순차적인 콜백 메서드가 있으며, 액티비티를 소멸시키는
+순차적인 콜백 메서드가 있습니다.</p>
+
+<p>이 과정에서는 가장 중요한 수명 주기 메서드에 대해 간략히 설명하며, 액티비티의 새 인스턴스를 생성하는 첫 번째 수명 주기 콜백을
+처리하는 방법을 보여줍니다.</p>
+
+
+
+<h2 id="lifecycle-states">수명 주기 콜백 이해하기</h2>
+
+<p>액티비티 수명 동안, 시스템은 계단식 피라미드와 비슷하게 수명 주기 메서드의 핵심 세트를
+순차적으로 호출합니다. 즉,
+액티비티 수명 주기의 각 단계는 피라미드의 각 계단과 같습니다. 시스템이 새 액티비티 인스턴스를 생성하면,
+각각의 콜백 메서드는 액티비티 상태를 한 단계 상향 이동합니다. 피라미드의 최상층은
+액티비티가 전면에서 실행 중이며 사용자가 이러한 액티비티와 상호 작용할 수 있는 단계를 뜻합니다.</p>
+
+<p>사용자가 액티비티를 나가면, 시스템은 액티비티를 해체하기 위해 액티비티
+상태를 피라미드에서 하향 이동하는 다른 메서드를 호출합니다. 경우에 따라, 액티비티가
+피라미드에서 완전히 하향 이동되지 않고 기다립니다(예: 사용자가 다른 앱으로 전환한 경우). 이런 경우,
+액티비티는 다시 피라미드 최상층으로 상향 이동될 수 있으며(사용자가 액티비티로 돌아갈 경우), 사용자는 종료한 지점에서
+작업을 재개할 수 있습니다.</p>
+
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle.png" />
+<p class="img-caption"><strong>그림 1.</strong> 액티비티
+수명 주기를 계단식 피라미드로 간략하게 표현한 그림. 이 그림에서는 최상층에 있는
+재개됨(Resumed) 상태를 향하여 액티비티를 한 단계 상향 이동하는 데 사용되는 각 콜백마다 하위 단계로
+액티비티를 하향 이동하는 콜백 메서드가 있음을 보여줍니다. 액티비티는
+일시정지됨(Paused) 및 정지됨(Stopped) 상태에서도 재개 상태로 돌아갈 수 있습니다.</p>
+
+
+<p>액티비티의 복잡한 정도에 따라, 모든
+수명 주기 메서드를 구현할 필요가 없는 경우도 있습니다. 하지만 각각의 수명 주기 메서드를 이해하고, 사용자가 예상한 대로
+앱이 동작하도록 필요한 수명 주기 메서드를 구현하는 것이 중요합니다. 액티비티 수명 주기 메서드를 올바르게 구현하면, 다음을 포함하여 여러 가지 방법으로 앱이 제대로 동작하도록
+보장할 수 있습니다.</p>
+<ul>
+ <li>사용자가 앱을 사용하는
+도중에 전화가 걸려오거나 다른 앱으로 전환할 때 충돌하지 않도록 합니다.</li>
+ <li>사용자가 앱을 활발하게 사용하지 않는 경우, 소중한 시스템 리소스를 소비하지
+않도록 합니다.</li>
+ <li>사용자가 앱에서 나갔다가 나중에 돌아왔을 때 사용자의 진행 상태를
+손실하지 않도록 합니다.</li>
+ <li>화면이 가로 방향과 세로 방향 간에 회전할 경우, 충돌하거나 사용자의
+진행 상태를 손실하지 않도록 합니다.</li>
+</ul>
+
+<!--
+<p class="table-caption"><strong>Table 1.</strong> Activity lifecycle state pairs and callback
+methods.</p>
+<table>
+ <tr>
+ <th scope="col">Lifecycle State</th>
+ <th scope="col">Startup Method</th>
+ <th scope="col">Teardown Method</th>
+ </tr>
+ <tr>
+ <td>Created / Destroyed</td>
+ <td>{@link android.app.Activity#onCreate onCreate()}</td>
+ <td>{@link android.app.Activity#onDestroy()}</td>
+ </tr>
+ <tr>
+ <td>Started / Stopped</td>
+ <td>{@link android.app.Activity#onStart()}</td>
+ <td>{@link android.app.Activity#onStop()}</td>
+ </tr>
+ <tr>
+ <td>Resumed / Resumed</td>
+ <td>{@link android.app.Activity#onResume()}</td>
+ <td>{@link android.app.Activity#onPause()}</td>
+ </tr>
+</table>
+-->
+
+<p>다음 과정에서 확인할 수 있듯이, 액티비티가 그림 1에 나와 있는 상태 간을
+전환하는 여러 가지 상황이 있습니다. 하지만, 이들 상태
+중 세 가지만 유일하게 정적일 수 있습니다. 즉, 액티비티는
+이 세 가지 상태에 한하여 그중 하나에서 장시간 동안 존재할 수 있습니다.</p>
+<dl>
+ <dt>재개됨(Resumed)</dt>
+ <dd>이 상태에서는 액티비티가 전면에 있으며 사용자가 액티비티와 상호 작용할 수
+있습니다(경우에 따라 "실행 중" 상태라고도 함).</dd>
+ <dt>일시정지됨(Paused)</dt>
+ <dd>이 상태에서는 액티비티가 다른 액티비티로 인해 부분적으로 가려져 있습니다. 이런 경우, 전면에 있는
+다른 액티비티는 반투명이거나 전체 화면을 차지하지 않습니다. 일시정지된
+액티비티는 사용자 입력을 받지 않으며, 어떠한 코드도 실행할 수 없습니다.
+ <dt>정지됨(Stopped)</dt>
+ <dd>이 상태에서는 액티비티가 완전히 가려져서 사용자에게 보이지 않습니다. 이 상태는 액티비티가 백그라운드에 있는 것으로
+간주됩니다. 정지되어 있는 동안 액티비티 인스턴스 및 멤버 변수와 같은 모든 상태
+정보가 유지되지만, 어떠한 코드도 실행할 수 없습니다.</dd>
+</dl>
+
+<p>이외의 상태(생성됨(Created) 및 시작됨(Started))는 일시적이며, 시스템은 다음 수명 주기 콜백 메서드를 호출하여
+다음 상태로 신속하게 전환합니다. 즉, 시스템은
+{@link android.app.Activity#onCreate onCreate()}를 호출한 후 바로 {@link
+android.app.Activity#onStart()}를 호출하고, 또 그 즉시 {@link
+android.app.Activity#onResume()}을 호출합니다.</p>
+
+<p>이것으로 기본적인 액티비티 수명 주기에 대한 설명을 마칩니다. 이제,
+구체적인 수명 주기 동작에 대해 알아보도록 하겠습니다.</p>
+
+
+
+<h2 id="launching-activity">앱 시작 관리자 액티비티 지정하기</h2>
+
+<p>사용자가 홈 화면에서 앱 아이콘을 선택하면, 시스템이 앱에서 "시작 관리자"(또는 "메인") 액티비티로 선언한 {@link android.app.Activity}에 대한 {@link
+android.app.Activity#onCreate onCreate()} 메서드를
+호출합니다. 이 액티비티는 앱의 사용자 인터페이스에 대한
+주 진입점 역할을 합니다.</p>
+
+<p>Android 매니페스트 파일인 <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">{@code AndroidManifest.xml}</a>에 메인 액티비티로 사용할 액티비티를 정의할 수 있습니다. 이 파일은
+프로젝트 디렉터리의 루트에 있습니다.</p>
+
+<p>앱의 메인 액티비티는 {@link
+android.content.Intent#ACTION_MAIN MAIN} 작업 및{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} 카테고리를 포함하는 <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a>와 함께
+매니페스트 파일에 선언되어야 합니다. 예를 들면 다음과 같습니다.</p>
+
+<pre>
+&lt;activity android:name=".MainActivity" android:label="&#64;string/app_name">
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.MAIN" />
+ &lt;category android:name="android.intent.category.LAUNCHER" />
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p class="note"><strong>참고:</strong> Android SDK
+Tools를 사용하여 새 Android 프로젝트를 생성하는 경우, 매니페스트에서 이 필터와 함께
+선언된 {@link android.app.Activity} 클래스가 기본 프로젝트 파일에 포함됩니다.</p>
+
+<p>{@link android.content.Intent#ACTION_MAIN MAIN} 작업 또는
+{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} 카테고리가
+액티비티 중 하나에 대해 선언되어 있지 않을 경우, 홈 화면의 앱 목록에 앱 아이콘이 표시되지 않습니다.</p>
+
+
+
+<h2 id="Create">새로운 인스턴스 생성하기</h2>
+
+<p>대부분의 앱은 사용자가 다양한 작업을 수행할 수 있도록 여러 액티비티를 포함하고 있습니다.
+액티비티가 사용자가 앱 아이콘을 클릭할 때 생성되는 메인 액티비티든, 사용자 작업에
+대한 응답으로 앱이 시작하는 다른 액티비티든 간에,
+시스템은 {@link
+android.app.Activity#onCreate onCreate()} 메서드를 호출하여 매번 {@link android.app.Activity}의 새 인스턴스를 생성합니다.</p>
+
+<p>액티비티의 전체 수명 주기 동안 한 번만 발생하는 기본
+애플리케이션 시작 논리를 수행하도록 {@link android.app.Activity#onCreate onCreate()} 메서드를 구현해야 합니다. 예를
+들어 {@link android.app.Activity#onCreate onCreate()}의 구현은
+사용자 인터페이스를 정의해야 하며, 몇몇 클래스 범위의 변수를 인스턴스화해야 할 수 있습니다.</p>
+
+<p>예를 들어 다음 {@link android.app.Activity#onCreate onCreate()}
+메서드에 대한 예제는
+사용자 인터페이스 선언(XML 레이아웃 파일에 정의), 멤버 변수 정의,
+몇몇 UI 구성과 같은 액티비티에 대한 몇 가지 기본 설정을 수행하는 코드를 보여줍니다.</p>
+
+<pre>
+TextView mTextView; // Member variable for text view in the layout
+
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Set the user interface layout for this Activity
+ // The layout file is defined in the project res/layout/main_activity.xml file
+ setContentView(R.layout.main_activity);
+
+ // Initialize member TextView so we can manipulate it later
+ mTextView = (TextView) findViewById(R.id.text_message);
+
+ // Make sure we're running on Honeycomb or higher to use ActionBar APIs
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ // For the main activity, make sure the app icon in the action bar
+ // does not behave as a button
+ ActionBar actionBar = getActionBar();
+ actionBar.setHomeButtonEnabled(false);
+ }
+}
+</pre>
+
+<p class="caution"><strong>주의:</strong> {@link android.os.Build.VERSION#SDK_INT}를 사용하여
+이전 시스템이 새 API를 실행하지 못하도록 방지하는 방법은 Android 2.0(API 레벨
+5) 이상에서만 가능합니다. 이전 버전에서는 런타임 예외가 발생합니다.</p>
+
+<p>{@link android.app.Activity#onCreate onCreate()}가 실행을 마치면 시스템은
+{@link android.app.Activity#onStart()} 및 {@link android.app.Activity#onResume()} 메서드를
+연달아 호출합니다. 액티비티가 생성됨(Created) 또는 시작됨(Started) 상태에서 머무르는 경우는 없습니다. 엄밀히 말하면
+{@link android.app.Activity#onStart()}가 호출되면 액티비티가 사용자에게 보이지만,
+{@link android.app.Activity#onResume()}이 바로 뒤따르고, 어떠한 상황(예: 전화가 오거나,
+사용자가 다른 액티비티로 전환하거나, 기기 화면이 꺼진 경우)이 발생하기 전까지는 액티비티가
+재개됨(Resumed) 상태로 유지됩니다.</p>
+
+<p>앞으로 진행되는 과정에서는 다른 시작 메서드인 {@link
+android.app.Activity#onStart()} 및 {@link android.app.Activity#onResume()}이 일시정지됨(Paused) 또는 정지됨(Stopped) 상태에서
+액티비티를 재개하기 위해 사용된 경우 액티비티의 수명 주기 동안 어떤 식으로 유용한지에 대해 설명합니다.</p>
+
+<p class="note"><strong>참고:</strong> {@link android.app.Activity#onCreate onCreate()}
+메서드는 <code>savedInstanceState</code>라고 하는 매개변수를 포함합니다. 이 매개변수는 <a href="recreating.html">액티비티 재생성하기</a>에 대한
+마지막 과정에서 설명합니다.</p>
+
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-create.png" />
+<p class="img-caption"><strong>그림 2.</strong> 액티비티의 새 인스턴스를 생성할 때
+시스템이 순차적으로 호출하는 {@link android.app.Activity#onCreate onCreate()}, {@link android.app.Activity#onStart()} 및 {@link android.app.Activity#onResume()}의
+세 가지 메인 콜백을 강조하여 보여주는 액티비티의 수명 주기 구조에
+대한 또 다른 그림. 이러한 순차적인
+콜백이 완료되면, 액티비티는 재개됨(Resumed) 상태가 됩니다. 이 상태에서는 사용자가 다른
+액티비티로 전환하기 전까지 사용자가 액티비티와 상호 작용할 수 있습니다.</p>
+
+
+
+
+
+
+
+<h2 id="Destroy">액티비티 소멸하기</h2>
+
+<p>액티비티의 첫 번째 수명 주기 콜백은 {@link android.app.Activity#onCreate
+onCreate()}이고, 마지막 콜백은 {@link android.app.Activity#onDestroy}입니다. 시스템은
+시스템 메모리에서 액티비티 인스턴스가 완전히 제거된다는 내용의 마지막
+신호로 액티비티에서 이 메서드를 호출합니다.</p>
+
+<p>대부분의 앱은 이 메서드를 구현할 필요가 없습니다. 왜냐하면 액티비티와
+함께 로컬 클래스 참조가 소멸되고, 액티비티가 {@link
+android.app.Activity#onPause} 및 {@link android.app.Activity#onStop} 중에 대부분 정리 작업을 수행하기 때문입니다. 하지만
+액티비티가 {@link
+android.app.Activity#onCreate onCreate()} 중에 생성한 백그라운드 스레드 또는 제대로 닫지 않으면 메모리 누수를
+야기할 수 있는 다른 장시간 실행되는 리소스를 포함하는 경우, {@link
+android.app.Activity#onDestroy} 중에 액티비티를 중단시켜야 합니다.</p>
+
+<pre>
+&#64;Override
+public void onDestroy() {
+ super.onDestroy(); // Always call the superclass
+
+ // Stop method tracing that the activity started during onCreate()
+ android.os.Debug.stopMethodTracing();
+}
+</pre>
+
+<p class="note"><strong>참고:</strong> 시스템은 한 가지 경우,
+즉 {@link android.app.Activity#onCreate onCreate()} 메서드에서 {@link
+android.app.Activity#finish()}를 호출하는 경우를 제외하고는, {@link android.app.Activity#onPause} 및 {@link
+android.app.Activity#onStop}을 먼저 호출한 후에 {@link android.app.Activity#onDestroy}를
+호출합니다. 경우에 따라(예: 액티비티가 다른 액티비티를
+실행하기 위한 임시 의사 결정자 역할을 할 경우), {@link
+android.app.Activity#onCreate onCreate()} 내에서 {@link android.app.Activity#finish()}를 호출하여 액티비티를 소멸시킬 수도 있습니다. 이 경우, 시스템이
+다른 수명 주기 메서드를 호출하지 않고 즉시
+{@link android.app.Activity#onDestroy}를 호출합니다.</p>
diff --git a/docs/html-intl/intl/ko/training/basics/activity-lifecycle/stopping.jd b/docs/html-intl/intl/ko/training/basics/activity-lifecycle/stopping.jd
new file mode 100644
index 0000000..79e713a
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/basics/activity-lifecycle/stopping.jd
@@ -0,0 +1,187 @@
+page.title=액티비티 정지 및 재시작하기
+page.tags=activity lifecycle
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>이 과정에서 다루는 내용</h2>
+ <ol>
+ <li><a href="#Stop">액티비티 정지하기</a></li>
+ <li><a href="#Start">액티비티 시작/재시작하기</a></li>
+ </ol>
+
+ <h2>필독 항목</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">액티비티</a>
+ </li>
+ </ul>
+
+<h2>실습하기</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">데모 다운로드</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>액티비티 수명 주기에서 액티비티를 제대로 정지하고 재시작하는 것은 중요한 프로세스입니다.
+그래야만 사용자가 앱이 항상 작동 상태를 유지하고 진행 상태를 손실하지 않는다고 인식하도록 할 수 있습니다.
+다음과 같이 액티비티가 정지되었다가 재시작되는 몇 가지 중요한 시나리오가 있습니다.</p>
+
+<ul>
+ <li>사용자가 최근 앱 창을 열고 다른 액티비티로 전환하면 현재 전면에 있는 앱의
+액티비티가 정지됩니다. 사용자가 홈 화면 시작 관리자 아이콘 또는 최근 앱 창에서
+앱으로 돌아오면 액티비티가 재시작됩니다.</li>
+ <li>사용자가 앱에서 새 액티비티를 시작하는 작업을 수행합니다. 두 번째 액티비티가
+생성되면 현재 액티비티가 정지됩니다. 사용자가 <em>뒤로</em>
+버튼을 누르면 첫 번째 액티비티가 재시작됩니다.</li>
+ <li>사용자가 앱을 사용하는 도중에 전화가 걸려옵니다.</li>
+</ul>
+
+<p>{@link android.app.Activity} 클래스는 두 가지 수명 주기 메서드인 {@link
+android.app.Activity#onStop()} 및 {@link android.app.Activity#onRestart()}를 제공합니다. 이 메서드를 사용하면 액티비티의 정지 및 재시작 처리 방법을
+명확하게 지정할 수 있습니다. 부분적인 UI 차단을 식별하는
+일시정지됨 상태와 달리, 정지됨 상태는 UI가 더 이상 보이지 않으며,
+사용자의 포커스가 별도의 액티비티 또는 완전히 별도의 앱에 있음을 보장합니다.</p>
+
+<p class="note"><strong>참고:</strong> {@link android.app.Activity}
+인스턴스가 정지되면 시스템이 이 인스턴스를 시스템 메모리에 유지하기 때문에
+{@link android.app.Activity#onStop()} 및 {@link android.app.Activity#onRestart()} 또는 {@link
+android.app.Activity#onStart()} 메서드 조차 구현할 필요가 없을 수도 있습니다. 비교적 간단한 액티비티의 경우 대부분,
+액티비티가 별 문제 없이 정지되고 재시작됩니다. 따라서 {@link
+android.app.Activity#onPause()}를 사용하여 진행 중인 작업을 일시정지하고 시스템 리소스와의 연결을 끊기만 하면 됩니다.</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-stopped.png" />
+<p class="img-caption"><strong>그림 1.</strong> 사용자가 액티비티를 떠나면, 시스템은
+{@link android.app.Activity#onStop onStop()}을 호출하여 액티비티를 정지시킵니다(1). 액티비티가 정지된 상태에서
+사용자가 돌아올 경우, 시스템은 {@link android.app.Activity#onRestart onRestart()}(2)
+를 호출하고, 곧바로 {@link android.app.Activity#onStart onStart()}(3) 및 {@link
+android.app.Activity#onResume()}(4)을 호출합니다. 어떤 시나리오로 인해 액티비티가
+정지되든 간에, 시스템은 항상 {@link
+android.app.Activity#onStop onStop()}을 호출하기 전에 {@link android.app.Activity#onPause onPause()}를 호출합니다.</p>
+
+
+
+<h2 id="Stop">액티비티 정지하기</h2>
+
+<p>{@link android.app.Activity#onStop()} 메서드에 대한 호출을 수신한 액티비티는 더
+이상 보이지 않게 되고, 사용자가
+사용하지 않는 동안 필요하지 않은 거의 모든 리소스를 해제해야 합니다. 액티비티가 정지되고 나면, 시스템이 시스템 메모리를
+회수해야 하는 경우 해당 인스턴스를 소멸할 수도 있습니다. 심한 경우, 시스템이 액티비티의 최종
+{@link android.app.Activity#onDestroy()} 콜백을 호출하지 않고 앱 프로세스만 단순하게 중단시킬 수도 있습니다. 따라서 {@link android.app.Activity#onStop()}을 사용하여
+메모리 누수를 야기시킬 수 있는 리소스를 해제하는 것이 중요합니다.</p>
+
+<p>{@link android.app.Activity#onStop()} 전에 {@link android.app.Activity#onPause onPause()}
+메서드가 호출되기는 하지만, 데이터베이스에 정보를 쓰는
+작업과 같이 규모가 크고 CPU를 많이 사용하는 종료 작업을 수행하는 경우
+{@link android.app.Activity#onStop onStop()}을 사용해야 합니다.</p>
+
+<p>다음은 영구적인 저장소에 노트 원고의 내용을
+저장하는 {@link android.app.Activity#onStop onStop()}을 구현하는 예제입니다.</p>
+
+<!-- TODO: Find a better example for onStop, because this kind of thing should probably use a
+separate thread but that's too complicated to show here. -->
+<pre>
+&#64;Override
+protected void onStop() {
+ super.onStop(); // Always call the superclass method first
+
+ // Save the note's current draft, because the activity is stopping
+ // and we want to be sure the current note progress isn't lost.
+ ContentValues values = new ContentValues();
+ values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
+ values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());
+
+ getContentResolver().update(
+ mUri, // The URI for the note to update.
+ values, // The map of column names and new values to apply to them.
+ null, // No SELECT criteria are used.
+ null // No WHERE columns are used.
+ );
+}
+</pre>
+
+<p>액티비티가 정지되면, {@link android.app.Activity} 개체는 메모리에 계속 유지되며,
+액티비티가 재개되면 다시 호출됩니다. 최상위 상태가 재개됨 상태인 콜백 메서드 중에
+생성된 구성요소는 다시 초기화할 필요가 없습니다. 또한 시스템은 레이아웃에 있는 각 {@link android.view.View}의 현재 상태도
+기록합니다. 따라서 사용자가 {@link android.widget.EditText} 위젯에 텍스트를
+입력하면 해당 내용이 저장되기 때문에 이를 저장 및 복원할
+필요가 없습니다.</p>
+
+<p class="note"><strong>참고:</strong> 시스템이 정지된 상태의 액티비티를 소멸시키는 경우에도,
+{@link android.os.Bundle}(키-값 쌍 Blob) 내에 {@link
+android.widget.EditText}와 같은 {@link android.view.View} 개체의 상태를 유지하고, 사용자가
+액티비티의 같은 인스턴스로 돌아오면 이를 복원합니다. 액티비티가 소멸되고 재생성될 경우, {@link android.os.Bundle}을 사용하여
+다른 상태 데이터를 저장하는 방법에 대해서는 <a href="recreating.html">다음 과정</a>에서 자세히 설명합니다.</p>
+
+
+
+<h2 id="Start">액티비티 시작/재시작하기</h2>
+
+<p>액티비티가 정지된 상태에서 전면으로 되돌아올 때
+{@link android.app.Activity#onRestart()}에 대한 호출을 수신합니다. 시스템은 {@link
+android.app.Activity#onStart()} 메서드도 호출합니다. 이 동작은 재시작되든, 아니면 처음 생성되든지에 상관없이
+액티비티가 보이게 될 때마다 발생합니다. 하지만 {@link
+android.app.Activity#onRestart()} 메서드는 액티비티가
+정지된 상태에서 재개되는 경우에만 호출됩니다. 따라서
+액티비티가 소멸된 것이 아니라 이전에 정지된 경우에 한하여 필요할 수 있는 특수 복원 작업을 수행하는 데 이 메서드를 사용할 수 있습니다.</p>
+
+<p>액티비티의 상태
+복원 작업에 앱이 {@link android.app.Activity#onRestart()}를 사용해야 하는 경우는 드물기 때문에
+일반 앱에 적용되는 이 메서드에 대한 가이드라인은 없습니다. 하지만 {@link android.app.Activity#onStop()}
+메서드는 모든 액티비티 리소스를 기본적으로 정리해야 하기 때문에, 액티비티가 재개되면
+다시 인스턴스화해야 합니다. 하지만 액티비티가 처음
+생성되는 경우(액티비티의 기존 인스턴스가 없을 경우)에도 인스턴스화해야 합니다. 따라서
+일반적으로 {@link android.app.Activity#onStart()} 콜백 메서드를 {@link android.app.Activity#onStop()} 메서드에 대한 상대
+메서드로 사용해야 합니다. 그 이유는 시스템이 액티비티를 생성할 때와
+액티비티를 정지된 상태에서 재시작할 때 모두 {@link
+android.app.Activity#onStart()}를 호출하기 때문입니다.</p>
+
+<p>예를 들어 사용자가 장시간 앱을 떠났다가 다시 앱으로
+돌아올 수 있기 때문에, {@link android.app.Activity#onStart()} 메서드는
+필요한 시스템 기능이 활성화되었는지 확인하기 위한 좋은 위치입니다.</p>
+
+<pre>
+&#64;Override
+protected void onStart() {
+ super.onStart(); // Always call the superclass method first
+
+ // The activity is either being restarted or started for the first time
+ // so this is where we should make sure that GPS is enabled
+ LocationManager locationManager =
+ (LocationManager) getSystemService(Context.LOCATION_SERVICE);
+ boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
+
+ if (!gpsEnabled) {
+ // Create a dialog here that requests the user to enable GPS, and use an intent
+ // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action
+ // to take the user to the Settings screen to enable GPS when they click "OK"
+ }
+}
+
+&#64;Override
+protected void onRestart() {
+ super.onRestart(); // Always call the superclass method first
+
+ // Activity being restarted from stopped state
+}
+</pre>
+
+
+
+
+<p>시스템이 액티비티를 소멸시킬 경우, {@link android.app.Activity}에 대해 {@link android.app.Activity#onDestroy()}
+메서드를 호출합니다. {@link
+android.app.Activity#onDestroy()}에 대한 호출을 수신하기 전에 {@link android.app.Activity#onStop()}을 사용하여 대부분의
+리소스를 해제했을 것이기 때문에 대부분의 앱의 경우 수행할 작업이 거의 없습니다. 이 메서드는 메모리 누수를 야기할 수 있는 리소스를 정리할 수 있는
+마지막 기회입니다. 이에 따라
+추가 스레드를 소멸시키고 메서드 추적과 같이 시간이 걸리는 기타 작업도
+정지되도록 할 수 있습니다.</p>
+
diff --git a/docs/html-intl/intl/ko/training/basics/data-storage/databases.jd b/docs/html-intl/intl/ko/training/basics/data-storage/databases.jd
new file mode 100644
index 0000000..e7ca166
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/basics/data-storage/databases.jd
@@ -0,0 +1,317 @@
+page.title=SQL 데이터베이스에 데이터 저장하기
+page.tags=data storage
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>이 과정에서 다루는 내용</h2>
+<ol>
+ <li><a href="#DefineContract">스키마 및 계약 정의하기</a></li>
+ <li><a href="#DbHelper">SQL Helper를 사용하여 데이터베이스 생성하기</a></li>
+ <li><a href="#WriteDbRow">데이터베이스에 정보 삽입하기</a></li>
+ <li><a href="#ReadDbRow">데이터베이스에서 정보 읽어오기</a></li>
+ <li><a href="#DeleteDbRow">데이터베이스에서 정보 삭제하기</a></li>
+ <li><a href="#UpdateDbRow">데이터베이스 업데이트하기</a></li>
+</ol>
+
+<h2>필독 항목</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#db">데이터베이스 사용하기</a></li>
+</ul>
+
+<!--
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/Sample.zip" class="button">Download the sample</a>
+ <p class="filename">Sample.zip</p>
+</div>
+-->
+
+</div>
+</div>
+
+
+<p>데이터베이스에 데이터를 저장하는 작업은
+연락처 정보와 같이 반복적이거나 구조적인 데이터에 이상적입니다. 이 클래스에서는 사용자가 SQL 데이터베이스에 대한 기본 사항에
+익숙하다는 전제하에
+Android에서 SQLite 데이터베이스를 시작하는 데 도움이 되는 유용한 정보를 제공합니다. Android에서
+데이터베이스를 사용할 때 필요한 API는 {@link android.database.sqlite} 패키지에 있습니다.</p>
+
+
+<h2 id="DefineContract">스키마 및 계약 정의하기</h2>
+
+<p>SQL 데이터베이스의 기본 원칙 중 하나는 스키마입니다. 스키마는 데이터베이스의 구성 체계에 대한 공식적인
+선언입니다. 스키마는 개발자가 데이터베이스를 생성할 때 사용하는 SQL
+문에 반영됩니다. <em>계약</em> 클래스라고 하는
+도우미 클래스를 생성하면 도움이 될 수 있습니다. 계약 클래스는 체계적이고
+자기 문서화 방식으로 스키마의 레이아웃을 명시적으로 지정합니다.</p>
+
+<p>계약 클래스는 URI, 테이블 및
+컬럼의 이름을 정의하는 상수를 유지하는 컨테이너입니다. 계약 클래스를 사용하면 동일한 패키지 내
+모든 클래스에 동일한 상수를 사용할 수 있습니다. 즉, 어느 한 장소에서 컬럼
+이름을 변경하면 코드 전체에 변경 사항이 반영됩니다.</p>
+
+<p>계약 클래스를 구성하는 좋은 방법은 클래스의 루트 레벨에 전체 데이터베이스에
+전역적인 정의를 추가하는 것입니다. 그런 다음 컬럼을 열거하는 각 테이블에 대해 내부
+클래스를 생성합니다.</p>
+
+<p class="note"><strong>참고:</strong> {@link
+android.provider.BaseColumns} 인터페이스를 구현함으로써, 내부 클래스는 {@code _ID}라고 하는 기본
+키 필드를 상속할 수 있습니다. 커서 어댑터와 같은 일부 Android 클래스의 경우
+내부 클래스가 이러한 기본 키 필드를 가지고 있을 것이라 예상합니다. 내부 클래스는 반드시 필요한 것은 아니지만, 데이터베이스가
+Android 프레임워크와 조화롭게 작업하는 데 도움이 될 수 있습니다.</p>
+
+<p>예를 들어, 다음 스니펫은 테이블 이름과
+단일 테이블의 컬럼 이름을 정의합니다.</p>
+
+
+<pre>
+public final class FeedReaderContract {
+ // To prevent someone from accidentally instantiating the contract class,
+ // give it an empty constructor.
+ public FeedReaderContract() {}
+
+ /* Inner class that defines the table contents */
+ public static abstract class FeedEntry implements BaseColumns {
+ public static final String TABLE_NAME = &quot;entry&quot;;
+ public static final String COLUMN_NAME_ENTRY_ID = &quot;entryid&quot;;
+ public static final String COLUMN_NAME_TITLE = &quot;title&quot;;
+ public static final String COLUMN_NAME_SUBTITLE = &quot;subtitle&quot;;
+ ...
+ }
+}
+</pre>
+
+
+
+<h2 id="DbHelper">SQL Helper를 사용하여 데이터베이스 생성하기</h2>
+
+<p>데이터베이스의 모양을 정의한 후에는 데이터베이스 및 테이블을 생성 및 유지하는
+메서드를 구현해야 합니다. 다음은 테이블을 생성하고 삭제하는 몇 가지 일반적인
+명령문입니다.</P>
+
+<pre>
+private static final String TEXT_TYPE = &quot; TEXT&quot;;
+private static final String COMMA_SEP = &quot;,&quot;;
+private static final String SQL_CREATE_ENTRIES =
+ &quot;CREATE TABLE &quot; + FeedEntry.TABLE_NAME + &quot; (&quot; +
+ FeedEntry._ID + &quot; INTEGER PRIMARY KEY,&quot; +
+ FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP +
+ FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
+ ... // Any other options for the CREATE command
+ &quot; )&quot;;
+
+private static final String SQL_DELETE_ENTRIES =
+ &quot;DROP TABLE IF EXISTS &quot; + FeedEntry.TABLE_NAME;
+</pre>
+
+<p>기기의 <a href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">내부
+저장소</a>에 저장하는 파일과 같이, Android는 데이터베이스를
+애플리케이션과 관련된 개인 디스크 공간에 저장합니다. 기본적으로 이 공간은 다른 애플리케이션이
+액세스할 수 없기 때문에 저장된 데이터는 안전하게 유지됩니다.</p>
+
+<p>유용한 API 집합이 {@link
+android.database.sqlite.SQLiteOpenHelper} 클래스에서 제공됩니다.
+데이터베이스에 대한 참조를 가져오기 위해 이 클래스를 사용하는 경우, 시스템은
+필요한 경우에 한해서만 데이터베이스 생성 및 업데이트와 같이
+장시간 실행될 수 있는 작업을
+수행하며, <em>앱이 시작되는 동안에는 이러한 작업을 수행하지 않습니다</em>.
+{@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase} 또는
+{@link android.database.sqlite.SQLiteOpenHelper#getReadableDatabase}를 호출하기만 하면 됩니다.</p>
+
+<p class="note"><strong>참고:</strong> 이러한 작업은 장시간 실행될 수도 있기 때문에
+{@link android.os.AsyncTask} 또는 {@link android.app.IntentService}와 같이 백그라운드 스레드에서 {@link
+android.database.sqlite.SQLiteOpenHelper#getWritableDatabase} 또는 {@link
+android.database.sqlite.SQLiteOpenHelper#getReadableDatabase}를
+호출해야 합니다.</p>
+
+<p>{@link android.database.sqlite.SQLiteOpenHelper}를 사용하려면 {@link
+android.database.sqlite.SQLiteOpenHelper#onCreate onCreate()}, {@link
+android.database.sqlite.SQLiteOpenHelper#onUpgrade onUpgrade()} 및 {@link
+android.database.sqlite.SQLiteOpenHelper#onOpen onOpen()} 콜백 메서드를
+재정의하는 하위 클래스를 생성합니다. 반드시 필요한 것은 아니지만
+{@link android.database.sqlite.SQLiteOpenHelper#onDowngrade onDowngrade()}도 구현해야 하는
+경우가 있을 수 있습니다.</p>
+
+<p>다음은 위에 표시된 명령 중 일부를 사용하여 구현한 {@link
+android.database.sqlite.SQLiteOpenHelper}의 예입니다.</p>
+
+<pre>
+public class FeedReaderDbHelper extends SQLiteOpenHelper {
+ // If you change the database schema, you must increment the database version.
+ public static final int DATABASE_VERSION = 1;
+ public static final String DATABASE_NAME = &quot;FeedReader.db&quot;;
+
+ public FeedReaderDbHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL(SQL_CREATE_ENTRIES);
+ }
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // This database is only a cache for online data, so its upgrade policy is
+ // to simply to discard the data and start over
+ db.execSQL(SQL_DELETE_ENTRIES);
+ onCreate(db);
+ }
+ public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ onUpgrade(db, oldVersion, newVersion);
+ }
+}
+</pre>
+
+<p>데이터베이스에 액세스하려면 {@link
+android.database.sqlite.SQLiteOpenHelper}의 하위 클래스를 인스턴스화합니다.</p>
+
+<pre>
+FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());
+</pre>
+
+
+
+
+<h2 id="WriteDbRow">데이터베이스에 정보 삽입하기</h2>
+
+<p>{@link android.content.ContentValues}
+개체를 {@link android.database.sqlite.SQLiteDatabase#insert insert()} 메서드에 전달하여 데이터를 데이터베이스에 삽입합니다.</p>
+
+<pre>
+// Gets the data repository in write mode
+SQLiteDatabase db = mDbHelper.getWritableDatabase();
+
+// Create a new map of values, where column names are the keys
+ContentValues values = new ContentValues();
+values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id);
+values.put(FeedEntry.COLUMN_NAME_TITLE, title);
+values.put(FeedEntry.COLUMN_NAME_CONTENT, content);
+
+// Insert the new row, returning the primary key value of the new row
+long newRowId;
+newRowId = db.insert(
+ FeedEntry.TABLE_NAME,
+ FeedEntry.COLUMN_NAME_NULLABLE,
+ values);
+</pre>
+
+<p>{@link android.database.sqlite.SQLiteDatabase#insert insert()}의
+첫 번째 인수는 테이블 이름입니다. 두 번째 인수는
+컬럼 이름을 제공합니다. 프레임워크는 {@link android.content.ContentValues}가 비어있을 경우
+여기에 NULL을 삽입할 수 있습니다. 만약 이를 {@code "null"}로 설정할 경우,
+값이 없으면 프레임워크가 행을 삽입하지 않습니다.</p>
+
+
+
+
+<h2 id="ReadDbRow">데이터베이스에서 정보 읽어오기</h2>
+
+<p>데이터베이스로부터 정보를 읽어오려면 {@link android.database.sqlite.SQLiteDatabase#query query()}
+메서드를 사용하고, 선택 기준과 원하는 컬럼을 전달합니다.
+이 메서드는 {@link android.database.sqlite.SQLiteDatabase#insert insert()}
+및 {@link android.database.sqlite.SQLiteDatabase#update update()} 요소를 결합합니다. 단, 삽입하려는 데이터보다는 가져오려는 데이터를
+정의하는 컬럼 목록은 예외입니다. 쿼리 결과는
+{@link android.database.Cursor} 개체로 반환됩니다.</p>
+
+<pre>
+SQLiteDatabase db = mDbHelper.getReadableDatabase();
+
+// Define a <em>projection</em> that specifies which columns from the database
+// you will actually use after this query.
+String[] projection = {
+ FeedEntry._ID,
+ FeedEntry.COLUMN_NAME_TITLE,
+ FeedEntry.COLUMN_NAME_UPDATED,
+ ...
+ };
+
+// How you want the results sorted in the resulting Cursor
+String sortOrder =
+ FeedEntry.COLUMN_NAME_UPDATED + " DESC";
+
+Cursor c = db.query(
+ FeedEntry.TABLE_NAME, // The table to query
+ projection, // The columns to return
+ selection, // The columns for the WHERE clause
+ selectionArgs, // The values for the WHERE clause
+ null, // don't group the rows
+ null, // don't filter by row groups
+ sortOrder // The sort order
+ );
+</pre>
+
+<p>커서 안의 행을 보려면 {@link android.database.Cursor} 이동
+메서드 중 하나를 사용합니다. 이 메서드는 값을 읽어오기 전에 항상 먼저 호출해야 합니다. 일반적으로 결과의
+처음 항목에 "읽기 위치"를 배치하는 {@link android.database.Cursor#moveToFirst}를 먼저
+호출해야 합니다. {@link android.database.Cursor#getString
+getString()} 또는 {@link android.database.Cursor#getLong getLong()}과 같은 {@link android.database.Cursor} 가져오기 메서드
+중 하나를 호출하여 각 행에 대한 컬럼 값을 읽어올 수 있습니다. 가져오기 메서드 각각에 대해
+원하는 컬럼의 인덱스 위치를 전달해야 하며, 이는
+{@link android.database.Cursor#getColumnIndex getColumnIndex()} 또는
+{@link android.database.Cursor#getColumnIndexOrThrow getColumnIndexOrThrow()}를 호출하여 가져올 수 있습니다.
+예를 들면 다음과 같습니다.</p>
+
+<pre>
+cursor.moveToFirst();
+long itemId = cursor.getLong(
+ cursor.getColumnIndexOrThrow(FeedEntry._ID)
+);
+</pre>
+
+
+
+
+<h2 id="DeleteDbRow">데이터베이스에서 정보 삭제하기</h2>
+
+<p>테이블에서 행을 삭제하려면 행을
+식별하는 선택 기준을 제공해야 합니다. 데이터베이스 API는 SQL 삽입을 방지하는 선택
+기준을 생성하는 메커니즘을 제공합니다. 이 메커니즘은
+선택 사양을 선택 절과 선택 인수로 나눕니다. 절은
+보려는 컬럼을 정의하고, 이를 통해 컬럼
+테스트를 결합할 수 있습니다. 인수는 절 안에 묶여 테스트되는 값입니다.
+이 결과는 일반 SQL 문과 같이 처리되지 않기 때문에 SQL 삽입의
+영향을 받지 않습니다.</p>
+
+<pre>
+// Define 'where' part of query.
+String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + &quot; LIKE ?&quot;;
+// Specify arguments in placeholder order.
+String[] selectionArgs = { String.valueOf(rowId) };
+// Issue SQL statement.
+db.delete(table_name, selection, selectionArgs);
+</pre>
+
+
+
+<h2 id="UpdateDbRow">데이터베이스 업데이트하기</h2>
+
+<p>데이터베이스 값의 하위 세트를 수정해야 하는 경우, {@link
+android.database.sqlite.SQLiteDatabase#update update()} 메서드를 사용합니다.</p>
+
+<p>테이블을 업데이트하면 {@link
+android.database.sqlite.SQLiteDatabase#insert insert()}의 콘텐츠 값 구문과
+{@link android.database.sqlite.SQLiteDatabase#delete delete()}의 {@code where} 구문이 결합됩니다.</p>
+
+<pre>
+SQLiteDatabase db = mDbHelper.getReadableDatabase();
+
+// New value for one column
+ContentValues values = new ContentValues();
+values.put(FeedEntry.COLUMN_NAME_TITLE, title);
+
+// Which row to update, based on the ID
+String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + &quot; LIKE ?&quot;;
+String[] selectionArgs = { String.valueOf(rowId) };
+
+int count = db.update(
+ FeedReaderDbHelper.FeedEntry.TABLE_NAME,
+ values,
+ selection,
+ selectionArgs);
+</pre>
+
diff --git a/docs/html-intl/intl/ko/training/basics/data-storage/files.jd b/docs/html-intl/intl/ko/training/basics/data-storage/files.jd
new file mode 100644
index 0000000..71652b5
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/basics/data-storage/files.jd
@@ -0,0 +1,379 @@
+page.title=파일 저장하기
+page.tags=data storage
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>이 과정에서 다루는 내용</h2>
+<ol>
+ <li><a href="#InternalVsExternalStorage">내부 또는 외부 저장소 선택하기</a></li>
+ <li><a href="#GetWritePermission">외부 저장소에 대한 권한 취득하기</a></li>
+ <li><a href="#WriteInternalStorage">내부 저장소에 파일 저장하기</a></li>
+ <li><a href="#WriteExternalStorage">외부 저장소에 파일 저장하기</a></li>
+ <li><a href="#GetFreeSpace">여유 공간 쿼리하기</a></li>
+ <li><a href="#DeleteFile">파일 삭제하기</a></li>
+</ol>
+
+<h2>필독 항목</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">내부
+ 저장소 사용하기</a></li>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#filesExternal">외부
+ 저장소 사용하기</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>Android는 다른 플랫폼의 디스크 기반 파일 시스템과
+유사한 파일 시스템을 사용합니다. 이 과정에서는 Android 파일 시스템에서 {@link java.io.File}
+API를 사용하여 파일을 읽고 쓰는 방법을
+설명합니다.</p>
+
+<p>{@link java.io.File} 개체는 대량의 데이터를 건너뛰지 않고
+처음부터 끝까지 순서대로 읽거나 쓸 때 적합합니다. 예를 들어 이미지 파일이나
+네트워크에서 교환되는 모든 항목에 적합합니다.</p>
+
+<p>이 과정에서는 앱에서 기본적인 파일 관련 작업을 수행하는 방법을 보여줍니다.
+여기서는 사용자가 Linux 파일 시스템에 대한 기본 사항과 {@link java.io}의
+표준 파일 입출력 API에 익숙하다고 가정합니다.</p>
+
+
+<h2 id="InternalVsExternalStorage">내부 또는 외부 저장소 선택하기</h2>
+
+<p>모든 Android 기기에는 "내부" 및 "외부" 저장소의 두 가지 파일 저장소 영역이 있습니다. 이 두 저장소의 이름은
+Android 초기에 만들어졌습니다. 당시 대부분의 기기가 비휘발성 내장 메모리(내부 저장소)와
+마이크로 SD 카드와 같은 이동식 저장 장치(외부 저장소)를 제공했습니다.
+일부 기기는 이동식 저장 장치 없이도 영구 저장소 공간을 "내부" 그리고 "외부" 파티션으로 나누어
+항상 두 개의 저장소 공간을 제공하며,
+API의 동작은 외부 저장소의 이동식 유무에 상관없이 일관적입니다.
+다음 목록에서는 각각의 저장소 공간에 대한 특징을 요약하여 보여줍니다.</p>
+
+<div class="col-5" style="margin-left:0">
+<p><b>내부 저장소:</b></p>
+<ul>
+<li>항상 사용 가능합니다.</li>
+<li>여기에 저장된 파일은 기본적으로 자신의 앱에서만 액세스할 수 있습니다.</li>
+<li>사용자가 앱을 삭제하면 시스템이
+내장 저장소에서 앱의 모든 파일을 제거합니다.</li>
+</ul>
+<p>내부 저장소는 사용자와 다른 앱이 자신의 파일에
+액세스하는 것을 원치 않을 때 가장 적합합니다.</p>
+</div>
+
+<div class="col-7" style="margin-right:0">
+<p><b>외부 저장소:</b></p>
+<ul>
+<li>항상 사용 가능하지는 않습니다. 그 이유는 사용자가 USB 저장소와 같은 외부 저장소를 마운트하고
+경우에 따라 기기에서 외부 저장소를 제거할 수 있기 때문입니다.</li>
+<li>모든 사람이 읽을 수 있기 때문에 자신이 제어할 수 있는 범위 외부에서 다른 사람이 여기에 저장된
+파일을 읽을 수도 있습니다.</li>
+<li>사용자가 앱을 삭제하면 {@link android.content.Context#getExternalFilesDir
+getExternalFilesDir()}의 디렉터리에 저장한 앱 파일에 한해서
+시스템이 제거합니다.</li>
+</ul>
+<p>외부 저장소는
+액세스 제한이 필요치 않은 파일과 다른 앱과 공유하기
+원하는 파일 또는 사용자가 컴퓨터에서 액세스할 수 있도록 허용하는 파일에 적합합니다.</p>
+</div>
+
+
+<p class="note" style="clear:both">
+<strong>팁:</strong> 기본적으로
+앱은 내부 저장소에 설치되지만 매니페스트에 <a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code
+android:installLocation}</a> 특성을 지정하여 외부 저장소에
+설치할 수도 있습니다. 사용자는 APK 크기가 매우 크고 내부 저장소 공간보다
+외부 저장소 공간이 더 클 때 이 옵션을 유용하게 활용할 수 있습니다. 자세한
+내용은 <a href="{@docRoot}guide/topics/data/install-location.html">앱 설치 위치</a>를 참조하세요.</p>
+
+
+<h2 id="GetWritePermission">외부 저장소에 대한 권한 취득하기</h2>
+
+<p>외부 저장소에 데이터를 쓰려면 <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">매니페스트 파일</a>에서
+{@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} 권한을 요청해야 합니다.</p>
+
+<pre>
+&lt;manifest ...>
+ &lt;uses-permission android:name=&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot; /&gt;
+ ...
+&lt;/manifest>
+</pre>
+
+<div class="caution"><p><strong>주의:</strong>
+현재는 모든 앱에서 특별한 권한 없이도 외부 저장소를
+읽을 수 있습니다. 하지만 이는 향후 릴리스에서 바뀔 예정입니다. 앱이
+외부 저장소에 데이터를 쓰지는 않고 읽어야만 해야 할 경우, {@link
+android.Manifest.permission#READ_EXTERNAL_STORAGE} 권한을 선언해야 합니다. 앱이 예상한 대로 계속
+작동하도록 하려면 변경 내용이 적용되기 전에 지금 이 권한을 선언해야 합니다.</p>
+<pre>
+&lt;manifest ...>
+ &lt;uses-permission android:name=&quot;android.permission.READ_EXTERNAL_STORAGE&quot; /&gt;
+ ...
+&lt;/manifest>
+</pre>
+<p>하지만 앱이 {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}
+권한을 사용하는 경우, 외부 저장소를 읽을 수 있는 권한도 묵시적으로 포함되어 있습니다.</p>
+</div>
+
+<p>내부
+저장소에 파일을 저장할 때는 어떠한 권한도 필요하지 않습니다. 애플리케이션은 내부 저장소 디렉터리에 있는 파일을 항상 읽고
+쓸 수 있는 권한을 가집니다.</p>
+
+
+
+
+
+<h2 id="WriteInternalStorage">내부 저장소에 파일 저장하기</h2>
+
+<p>내부 저장소에 파일을 저장할 경우, 다음 두 메서드 중 하나를 호출하여 적합한 디렉터리를
+{@link java.io.File}로 얻을 수 있습니다.</p>
+
+<dl>
+ <dt>{@link android.content.Context#getFilesDir}</dt>
+ <dd>앱에 대한 내부 디렉터리를 나타내는 {@link java.io.File}을 반환합니다.</dd>
+ <dt>{@link android.content.Context#getCacheDir}</dt>
+ <dd>앱의 임시
+캐시 파일에 대한 내부 디렉터리를 나타내는 {@link java.io.File}을 반환합니다. 더 이상
+필요하지 않은 파일은 모두 삭제하고 언제든지
+사용할 수 있는 메모리 크기에 합리적인 크기 제한(예. 1MB)을 구현해야 합니다. 저장 공간이 부족해지기 시작하면 경고 없이 시스템이 캐시 파일을
+삭제할 수도 있습니다.</dd>
+</dl>
+
+<p>이러한 디렉터리 중 하나에서 새 파일을 생성하려면 {@link
+java.io.File#File(File,String) File()} 생성자를 사용하고 내부 저장소 디렉터리를 지정하는 상기 메서드 중
+하나를 통해 제공되는 {@link java.io.File}을 전달하면 됩니다. 예를 들면 다음과 같습니다.</p>
+
+<pre>
+File file = new File(context.getFilesDir(), filename);
+</pre>
+
+<p>또한, {@link
+android.content.Context#openFileOutput openFileOutput()}을 호출하여 내부 디렉터리의 파일에 데이터를 쓰는
+{@link java.io.FileOutputStream}을 가져올 수도 있습니다. 다음 예는
+몇몇 텍스트를 파일에 쓰는 방법을 보여줍니다.</p>
+
+<pre>
+String filename = "myfile";
+String string = "Hello world!";
+FileOutputStream outputStream;
+
+try {
+ outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
+ outputStream.write(string.getBytes());
+ outputStream.close();
+} catch (Exception e) {
+ e.printStackTrace();
+}
+</pre>
+
+<p>또는, 파일을 캐싱해야 할 경우 {@link
+java.io.File#createTempFile createTempFile()}을 대신 사용합니다. 예를 들어 다음 메서드는 {@link java.net.URL}에서
+파일 이름을 추출한 후 해당 이름을 사용하여
+앱의 내부 캐시 디렉터리에 파일을 생성합니다.</p>
+
+<pre>
+public File getTempFile(Context context, String url) {
+ File file;
+ try {
+ String fileName = Uri.parse(url).getLastPathSegment();
+ file = File.createTempFile(fileName, null, context.getCacheDir());
+ catch (IOException e) {
+ // Error while creating file
+ }
+ return file;
+}
+</pre>
+
+<p class="note"><strong>참고:</strong>
+앱의 내부 저장소 디렉터리는 Android 파일 시스템의 특별한 위치에 있는 앱의 패키지 이름으로
+지정됩니다.
+엄밀히 말하면, 파일 모드를
+읽기 가능으로 설정할 경우 다른 앱이 내부 파일을 읽을 수 있습니다. 하지만 이는 다른 앱도 여러분 자신의 앱 패키지
+이름 및 파일 이름을 알아야 가능합니다. 다른 앱은 여러분 자신의 내부 디렉터리를 탐색할 수 없으며 명시적으로
+읽기 가능 및 쓰기 가능으로 파일을 설정하지 않으면 파일을 읽거나 쓸 수 없습니다. 따라서
+{@link android.content.Context#MODE_PRIVATE}을 내부 저장소 내 파일에 사용하는 한,
+다른 앱이 이러한 파일에 액세스할 수 없습니다.</p>
+
+
+
+
+
+<h2 id="WriteExternalStorage">외부 저장소에 파일 저장하기</h2>
+
+<p>사용자가
+외부 저장소를 PC에 마운트했거나 외부 저장소를 제공하는 SD 카드를 제거한 경우 등에는 외부 저장소를 사용할 수 없기 때문에 액세스하기 전
+항상 볼륨이 사용 가능한지 확인해야 합니다. {@link android.os.Environment#getExternalStorageState}를 호출하여 외부
+저장소 상태를 쿼리할 수 있습니다. 반환된
+상태가 {@link android.os.Environment#MEDIA_MOUNTED}와 동일하다면 파일을 읽거나 파일에
+쓸 수 있습니다. 예를 들어 다음 메서드는 저장소의
+가용성을 확인하는 데 유용합니다.</p>
+
+<pre>
+/* Checks if external storage is available for read and write */
+public boolean isExternalStorageWritable() {
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+ return false;
+}
+
+/* Checks if external storage is available to at least read */
+public boolean isExternalStorageReadable() {
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
+ }
+ return false;
+}
+</pre>
+
+<p>외부 저장소는 사용자 및 다른 앱에 의해 수정될 수 있으나, 여기에 저장할 수 있는 파일로는 두 가지
+범주가 있습니다.</p>
+
+<dl>
+ <dt>공용 파일</dt>
+ <dd>다른 앱 및 사용자가 자유롭게 사용할 수 있는
+파일입니다. 사용자가 앱을 제거해도 사용자는
+이러한 파일을 여전히 사용할 수 있습니다.
+ <p>예를 들어 앱으로 캡처된 사진 또는 기타 다운로드된 파일이 이에 해당합니다.</p>
+ </dd>
+ <dt>개인 파일</dt>
+ <dd>앱에 속한 파일이며, 사용자가
+앱을 제거하면 같이 삭제됩니다. 이러한 파일은
+엄밀히 말해 외부 저장소에 저장된 파일이기 때문에 사용자 및 다른 앱의 액세스가 가능하긴 하지만, 앱 외부에서
+사용자에게 값을 실제로 제공하지는 않습니다. 사용자가 앱을 제거하면 앱의 외부 개인 디렉터리 내 모든 파일을 시스템에서
+삭제합니다.
+ <p>예를 들어 앱에서 다운로드한 추가 리소스 또는 임시 미디어 파일이 이에 해당합니다.</p>
+ </dd>
+</dl>
+
+<p>외부 저장소에 공용 파일을 저장하려는 경우
+{@link android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()} 메서드를 사용하여 외부 저장소에 적절한 디렉터리를 나타내는
+{@link java.io.File}을 가져옵니다. 이 메서드는 {@link android.os.Environment#DIRECTORY_MUSIC} 또는 {@link
+android.os.Environment#DIRECTORY_PICTURES}와 같은 다른 공개
+파일과 논리적으로 구성될 수 있도록 저장하고자 하는 파일의 유형을
+지정하는 인수를 받습니다. 예를 들면 다음과 같습니다.</p>
+
+<pre>
+public File getAlbumStorageDir(String albumName) {
+ // Get the directory for the user's public pictures directory.
+ File file = new File(Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES), albumName);
+ if (!file.mkdirs()) {
+ Log.e(LOG_TAG, "Directory not created");
+ }
+ return file;
+}
+</pre>
+
+
+<p>개인 파일을 앱에 저장하고자 하는 경우, {@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()}을 호출하고 원하는 디렉터리 유형을
+나타내는 이름을 전달하여
+적절한 디렉터리를 얻을 수 있습니다. 이런 식으로 생성된 각 디렉터리는 부모
+디렉터리에 추가됩니다. 이 디렉터리는
+사용자가 앱을 제거할 때 시스템이 삭제하는 앱의 모든 외부 저장소 파일을 캡슐화합니다.</p>
+
+<p>예를 들어, 다음은 개인 사진 앨범을 위한 디렉터리 생성 시 사용 가능한 메서드입니다.</p>
+
+<pre>
+public File getAlbumStorageDir(Context context, String albumName) {
+ // Get the directory for the app's private pictures directory.
+ File file = new File(context.getExternalFilesDir(
+ Environment.DIRECTORY_PICTURES), albumName);
+ if (!file.mkdirs()) {
+ Log.e(LOG_TAG, "Directory not created");
+ }
+ return file;
+}
+</pre>
+
+<p>미리 정의된 하위 디렉터리 이름 중 파일에 알맞은 이름이 없을 경우 대신 {@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()}을 호출하고 {@code null}을 전달할 수 있습니다. 그러면
+앱의 외부 저장소 내 개인 디렉터리의 루트 디렉터리가 반환됩니다.</p>
+
+<p>사용자가 앱을 제거할 때 {@link android.content.Context#getExternalFilesDir getExternalFilesDir()}이
+삭제된 디렉터리 내에 디렉터리를 생성한다는 것을 기억하세요.
+앱이 카메라이고 사용자가 사진을 계속 간직하고자 하는 경우처럼, 사용자가
+앱을 제거한 후에도 본인이 저장하는 파일을 사용 가능하게 유지해야 하는 경우 {@link android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()}를
+대신 사용해야 합니다.</p>
+
+
+<p>공유 파일에 {@link
+android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()}를 사용하든,
+개인 파일에 {@link android.content.Context#getExternalFilesDir
+getExternalFilesDir()}을 사용하든지에 관계없이 {@link android.os.Environment#DIRECTORY_PICTURES}와
+같이 API 상수로 제공되는
+디렉터리 이름을 사용해야 합니다. 이러한 디렉터리 이름은
+시스템이 파일을 적절하게 처리할 수 있게 해줍니다. 예를 들어 {@link
+android.os.Environment#DIRECTORY_RINGTONES}에 저장된 파일은 시스템 미디어 스캐너에 의해 음악
+대신 벨소리로 분류됩니다.</p>
+
+
+
+
+<h2 id="GetFreeSpace">여유 공간 쿼리하기</h2>
+
+<p>저장하는 데이터의 크기를 미리 알고 있을 경우, {@link java.io.File#getFreeSpace} 또는 {@link
+java.io.File#getTotalSpace}를 호출하여 {@link
+java.io.IOException}을 초래하지 않고 사용 공간이 충분한지
+확인할 수 있습니다. 이러한 메서드는 각각 저장소 볼륨에서 현재 사용 가능한 공간 및
+전체 공간을 알려줍니다. 이 정보는 일정 임계치를 초과하는 수준으로
+저장소 볼륨이 차는 것을 방지하는 데도 유용합니다.</p>
+
+<p>하지만 시스템은 {@link java.io.File#getFreeSpace}로
+지정된 만큼의 바이트를 쓸 수 있다고 보장하지 않습니다. 저장하고자 하는 데이터의 크기보다 반환된 숫자가
+몇 MB 더 클 경우 또는 파일 시스템이 90%
+미만으로 찼을 경우 안심하고 작업을 진행할 수 있습니다.
+그렇지 않다면 저장소에 데이터를 쓰지 않는 것이 좋습니다.</p>
+
+<p class="note"><strong>참고:</strong> 파일을 저장하기 전에
+사용 가능한 공간을 꼭 확인할 필요는 없습니다. 대신, 파일을 곧바로 쓴 후 {@link java.io.IOException}이 발생하는 경우 이를
+캐치하면 됩니다. 필요한 공간을 정확히 모르는 경우
+이러한 방법을 사용할 수 있습니다. 예를 들어 파일을 저장하기 전에 PNG 이미지를
+JPEG로 변환하여 파일 인코딩을
+변경하는 경우, 파일의 크기를 사전에 알 수 없습니다.</p>
+
+
+
+
+<h2 id="DeleteFile">파일 삭제하기</h2>
+
+<p>더 이상 필요하지 않은 파일은 항상 삭제해야 합니다. 파일을 삭제하는 가장 간단한 방법은 열린
+파일 참조가 {@link java.io.File#delete}를 직접 호출하도록 하는 것입니다.</p>
+
+<pre>
+myFile.delete();
+</pre>
+
+<p>파일이 내부 저장소에 저장되어 있는 경우, {@link android.content.Context}에 위치를 요청하고 {@link android.content.Context#deleteFile deleteFile()}을 호출하여 파일을
+삭제할 수도 있습니다.</p>
+
+<pre>
+myContext.deleteFile(fileName);
+</pre>
+
+<div class="note">
+<p><strong>참고:</strong> 사용자가 앱을 제거하면 Android 시스템이
+다음 항목을 삭제합니다.</p>
+<ul>
+<li>내부 저장소에 저장한 모든 파일</li>
+<li>{@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()}을 사용해 외부 저장소에 저장한 모든 파일</li>
+</ul>
+<p>하지만
+{@link android.content.Context#getCacheDir()}로 생성된 모든 캐시 파일과 더 이상 필요치 않은
+다른 파일은 정기적으로 직접 삭제해야 합니다.</p>
+</div>
+
diff --git a/docs/html-intl/intl/ko/training/basics/data-storage/index.jd b/docs/html-intl/intl/ko/training/basics/data-storage/index.jd
new file mode 100644
index 0000000..d6c118d
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/basics/data-storage/index.jd
@@ -0,0 +1,57 @@
+page.title=데이터 저장하기
+page.tags=data storage,files,sql,database,preferences
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>종속관계 및 전제조건</h2>
+<ul>
+ <li>Android 1.6(API 레벨 4) 또는 그 이상</li>
+ <li>맵 키-값 컬렉션에 정통한 지식</li>
+ <li>Java file I/O API에 정통한 지식</li>
+ <li>SQL 데이터베이스에 정통한 지식</li>
+</ul>
+
+<h2>필독 항목</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html">저장소 옵션</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>대부분의 Android 앱은 데이터를 저장해야 합니다. 하다못해 {@link android.app.Activity#onPause onPause()} 동안에도 사용자의 진행 상태가 손실되지 않도록
+앱 상태에 대한 정보만이라도 저장합니다. 또한, 대부분의
+단순하지 않은 앱은 사용자 설정을 저장해야 하며, 어떤 앱은 파일 및 데이터베이스에서 대량의
+정보를 관리해야 합니다. 이 클래스에서는 다음 사항을 포함해 Android의
+주요 데이터 저장소 옵션에 대해 소개합니다.</p>
+
+<ul>
+ <li>공유
+기본 설정 파일에 간단한 데이터 유형의 키-값 쌍 저장하기</li>
+ <li>Android 파일 시스템에 임의의 파일 저장하기</li>
+ <li>SQLite로 관리되는 데이터베이스 사용하기</li>
+</ul>
+
+
+<h2>과정</h2>
+
+<dl>
+ <dt><b><a href="shared-preferences.html">키-값 세트 저장하기</a></b></dt>
+ <dd>키-값 쌍
+내에 소량의 정보를 저장하기 위해 공유 기본 설정 파일을 사용하는 방법을 설명합니다.</dd>
+
+ <dt><b><a href="files.html">파일 저장하기</a></b></dt>
+ <dd>일반적으로 순서대로 읽혀지는
+긴 데이터 시퀀스를 저장하는 것과 같이 기본적인 파일 저장에 대해 설명합니다.</dd>
+
+ <dt><b><a href="databases.html">SQL 데이터베이스에 데이터 저장하기</a></b></dt>
+ <dd>SQLite 데이터베이스를 사용하여 구조화된 데이터를 읽고 쓰는 방법에 대해 설명합니다.</dd>
+
+</dl>
diff --git a/docs/html-intl/intl/ko/training/basics/data-storage/shared-preferences.jd b/docs/html-intl/intl/ko/training/basics/data-storage/shared-preferences.jd
new file mode 100644
index 0000000..f47d7e7
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/basics/data-storage/shared-preferences.jd
@@ -0,0 +1,120 @@
+page.title=키-값 세트 저장하기
+page.tags=data storage
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>이 과정에서 다루는 내용</h2>
+<ol>
+ <li><a href="#GetSharedPreferences">SharedPreferences에 대한 핸들 가져오기</a></li>
+ <li><a href="#WriteSharedPreference">SharedPreferences에 쓰기</a></li>
+ <li><a href="#ReadSharedPreference">SharedPreferences에서 읽어오기</a></li>
+</ol>
+
+<h2>필독 항목</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#pref">SharedPreferences 사용하기</a></li>
+</ul>
+
+</div>
+</div>
+
+
+<p>저장하고자 하는 키-값 컬렉션이 비교적 작은 경우,
+{@link android.content.SharedPreferences} API를 사용합니다.
+{@link android.content.SharedPreferences} 개체는
+키-값 쌍을 포함하는 파일을 가리키며, 키-값 쌍을 읽고 쓸 수 있는 간단한 메서드를 제공합니다. 각
+{@link android.content.SharedPreferences} 파일은 프레임워크로
+관리되며, 전용 또는 공유일 수 있습니다.</p>
+
+<p>이 클래스에서는 {@link android.content.SharedPreferences} API를 사용하여 단순한 값을 저장하고
+가져오는 방법을 보여줍니다.</p>
+
+<p class="note"><strong>참고:</strong> {@link android.content.SharedPreferences} API는
+키-값 쌍을 읽고 쓰는 용도로만 사용됩니다. 또한, (앱 설정을 저장하는 데 대한 구현으로 {@link android.content.SharedPreferences}를
+사용하기는 하지만) 앱 설정을 위한
+사용자 인터페이스 구축을 지원하는
+{@link android.preference.Preference} API와 혼동해서는 안 됩니다. {@link
+android.preference.Preference} API 사용에 대한 자세한 내용은 <a href="{@docRoot}guide/topics/ui/settings.html">설정</a> 가이드를 참조하세요.</p>
+
+<h2 id="GetSharedPreferences">SharedPreferences에 대한 핸들 가져오기</h2>
+
+<p>다음 두 메서드 중
+하나를 호출하여 새로운 공유 기본 설정 파일을 생성하거나 기존 파일에 액세스할 수 있습니다.</p>
+<ul>
+ <li>{@link android.content.Context#getSharedPreferences(String,int)
+getSharedPreferences()} &mdash; 여러 공유 기본 설정 파일이 필요한 경우 이 메서드를 사용합니다. 이러한 파일은 첫 번째 매개변수로 지정하는
+이름으로 식별됩니다. 앱 내부의 모든
+{@link android.content.Context}에서 이 메서드를 호출할 수 있습니다.</li>
+ <li>{@link android.app.Activity#getPreferences(int) getPreferences()} &mdash; 액티비티에
+하나의 공유 기본 설정 파일만 사용해야 하는 경우
+{@link android.app.Activity}에서 이 메서드를 사용합니다. 이 메서드는 액티비티에 속한 기본 공유
+기본 설정 파일을 가져오기 때문에 이름을 제공할 필요가 없습니다.</li>
+</ul>
+
+<p>예를 들어 다음 코드는 {@link android.app.Fragment} 내부에서 실행됩니다.
+이 코드는 리소스 문자열 {@code R.string.preference_file_key}에 의해
+식별되는 공유 기본 설정 파일에 액세스하며, 본인의 앱만 파일에 액세스할 수 있도록 전용 모드에서
+파일을 엽니다.</p>
+
+<pre>
+Context context = getActivity();
+SharedPreferences sharedPref = context.getSharedPreferences(
+ getString(R.string.preference_file_key), Context.MODE_PRIVATE);
+</pre>
+
+<p>공유 기본 설정 파일의 이름을 지정할 때는 {@code "com.example.myapp.PREFERENCE_FILE_KEY"}와 같이 앱에
+대한 고유 식별 이름을 사용해야 합니다.</p>
+
+<p>또는, 액티비티에 공유 기본 설정 파일만 필요할 경우
+{@link android.app.Activity#getPreferences(int) getPreferences()} 메서드를 사용할 수 있습니다.</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+</pre>
+
+<p class="caution"><strong>주의:</strong> {@link android.content.Context#MODE_WORLD_READABLE} 또는 {@link
+android.content.Context#MODE_WORLD_WRITEABLE}을
+사용하여 공유 기본 설정 파일을 생성하는 경우, 파일 식별자를 인식하는 기타 모든 앱이
+데이터에 액세스할 수 있습니다.</p>
+
+
+<h2 id="WriteSharedPreference">SharedPreferences에 쓰기</h2>
+
+<p>공유 기본 설정 파일에 데이터를 쓰려면 {@link android.content.SharedPreferences}에서 {@link
+android.content.SharedPreferences#edit}를 호출하여 {@link
+android.content.SharedPreferences.Editor}를 생성해야 합니다.</p>
+
+<p>{@link
+android.content.SharedPreferences.Editor#putInt putInt()} 및 {@link
+android.content.SharedPreferences.Editor#putString putString()}과 같은 메서드를 사용하여 쓰고자 하는 키와 값을 전달합니다. 그런 다음 {@link
+android.content.SharedPreferences.Editor#commit}을 호출하여 변경 내용을 저장합니다. 예를 들면 다음과 같습니다.</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+SharedPreferences.Editor editor = sharedPref.edit();
+editor.putInt(getString(R.string.saved_high_score), newHighScore);
+editor.commit();
+</pre>
+
+
+<h2 id="ReadSharedPreference">SharedPreferences에서 읽어오기</h2>
+
+<p>공유 기본 설정 파일에서 값을 가져오려면 원하는 값에
+대한 키를 제공하고 원하는 경우 키가
+없을 경우 반환할 기본값을 제공하여 {@link
+android.content.SharedPreferences#getInt getInt()} 및 {@link
+android.content.SharedPreferences#getString getString()}과 같은 메서드를 호출해야 합니다. 예를 들면 다음과 같습니다.</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+int defaultValue = getResources().getInteger(R.string.saved_high_score_default);
+long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue);
+</pre>
+
diff --git a/docs/html-intl/intl/ko/training/basics/intents/filters.jd b/docs/html-intl/intl/ko/training/basics/intents/filters.jd
new file mode 100644
index 0000000..265534c
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/basics/intents/filters.jd
@@ -0,0 +1,236 @@
+page.title=다른 앱이 자신의 액티비티를 시작하도록 허용하기
+page.tags=intents
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>이 과정에서 다루는 내용</h2>
+<ol>
+ <li><a href="#AddIntentFilter">인텐트 필터 추가하기</a></li>
+ <li><a href="#HandleIntent">액티비티에서 인텐트 처리하기</a></li>
+ <li><a href="#ReturnResult">결과 반환하기</a></li>
+</ol>
+
+<h2>필독 항목</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">간단한 데이터 공유하기</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">파일 공유하기</a>
+</ul>
+ </div>
+</div>
+
+<p>앞의 두 과정은 이야기의 한 면인 자신의 앱에서
+다른 앱의 액티비티를 시작하는 것에 초점을 뒀습니다. 그러나 자신의 앱이 다른 앱에 유용할 수 있는 작업을 수행할 수 있는 경우
+다른 앱의 작업 요청에 응답할 수 있도록 준비되어 있어야 합니다. 예를 들어, 사용자가
+친구와 메시지 또는 사진을 공유할 수 있는 소셜 앱을 만드는 경우 사용자가 다른 앱에서
+"공유" 작업을 시작하고 이 작업을 수행하기 위해 여러분 자신의 앱을 시작할 수 있도록
+{@link android.content.Intent#ACTION_SEND} 인텐트를 지원하는 것이 좋습니다.</p>
+
+<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>앱이 기기에 설치되면 시스템이 인텐트
+필터를 식별한 후 설치된 모든 앱에서 지원되는 인텐트의 내부 카탈로그에 해당 정보를 추가합니다.
+앱이 암묵적인 인텐트를 사용하여 {@link android.app.Activity#startActivity
+startActivity()} 또는 {@link android.app.Activity#startActivityForResult startActivityForResult()}를
+호출하면 시스템이 인텐트에 응답 가능한 액티비티(또는 여러 액티비티)를
+찾습니다.</p>
+
+
+
+<h2 id="AddIntentFilter">인텐트 필터 추가하기</h2>
+
+<p>액티비티가 처리 가능한 인텐트를 올바르게 정의하려면 액티비티가
+받아들이는 데이터와 작업 유형 측면에서
+추가하는 인텐트 필터가 최대한 구체적이어야 합니다.</p>
+
+<p>액티비티의 인텐트 필터가 {@link android.content.Intent} 개체의 다음 기준을 충족할
+경우, 시스템이 주어진 {@link android.content.Intent}를 해당 액티비티에 보낼 수 있습니다.</p>
+
+<dl>
+ <dt>작업</dt>
+ <dd>수행할 작업의 이름을 지정하는 문자열입니다. 일반적으로, 플랫폼에서 정의하는 값 중
+하나입니다(예: {@link android.content.Intent#ACTION_SEND} 또는 {@link android.content.Intent#ACTION_VIEW}).
+ <p><a href="{@docRoot}guide/topics/manifest/action-element.html">{@code &lt;action&gt;}</a> 요소를 사용하여 인텐트 필터에 지정합니다.
+이 요소에 지정하는 값은 API 상수 대신
+작업의 전체 문자열 이름이어야 합니다(다음 예제 참조).</p></dd>
+
+ <dt>데이터</dt>
+ <dd>인텐트와 관련된 데이터에 대한 설명입니다.
+ <p><a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data&gt;}</a> 요소를 사용하여 인텐트 필터에 지정합니다. 이 요소에서
+하나 이상의 특성을 사용하여 MIME 유형, URI 접두사, URI 스키마, 또는
+이들의 조합 그리고 수락된 데이터 유형을 나타내는 다른 요소들을 지정할 수
+있습니다.</p>
+ <p class="note"><strong>참고:</strong> 액티비티가 URI가 아닌
+다른 종류의 "엑스트라" 데이터를 처리할 때와 같이, 데이터
+{@link android.net.Uri}에 대한 세부사항을 선언할 필요가 없는 경우, {@code text/plain} 또는 {@code image/jpeg}와 같이 액티비티가 처리하는 데이터
+유형을 선언하는 데 {@code android:mimeType} 특성만 지정하면 됩니다.</p>
+</dd>
+ <dt>카테고리</dt>
+ <dd>인텐트를 처리하는 액티비티의 특징을 지정할 수 있는 추가적인 방법을 제공합니다. 일반적으로, 사용자 제스처 또는 이러한 제스처가 시작된 위치와
+관련되어 있습니다. 시스템이 지원하는 카테고리는
+여러 가지가 있지만 대부분은 거의 사용되지 않습니다. 하지만 모든 암묵적인 인텐트는 기본적으로
+{@link android.content.Intent#CATEGORY_DEFAULT}로 정의됩니다.
+ <p><a href="{@docRoot}guide/topics/manifest/category-element.html">{@code &lt;category&gt;}</a> 요소를 사용하여 인텐트 필터에
+지정합니다.</p></dd>
+</dl>
+
+<p>인텐트 필터에서 액티비티가 허용하는 기준을 선언할 수 있습니다.
+이는 이러한 기준 각각을 <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter&gt;}</a> 요소 내에 해당 XML 요소를 중첩하여 선언하면
+가능합니다.</p>
+
+<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;data android:mimeType="image/*"/>
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p>수신되는 인텐트는 각각 하나의 작업 및 하나의 데이터 유형만 지정합니다. 하지만
+<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a> 각각에 <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> 및 <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code
+&lt;data&gt;}</a>에 대한 여러
+인스턴스를 선언해도 문제가 되지는 않습니다.</p>
+
+<p>작업 및 데이터의 두 쌍이 상호 배타적으로
+동작할 경우, 어떤 데이터 유형과 페어링되었을 때 어떤 작업이 허용 가능한지를 지정하는
+인텐트 필터를 각각 따로 생성해야 합니다.</p>
+
+<p>예를 들어 액티비티가 {@link
+android.content.Intent#ACTION_SEND} 및 {@link
+android.content.Intent#ACTION_SENDTO} 인텐트 모두에서 텍스트와 이미지 모두를 처리한다고 가정합니다. 이런 경우, 두 작업 각각에 별도의
+인텐트 필터를 정의해야 합니다. 그 이유는 {@link
+android.content.Intent#ACTION_SENDTO} 인텐트는 데이터 {@link android.net.Uri}를 사용해서 {@code send} 또는 {@code sendto} URI 스키마를 사용하는
+수신자 주소를 지정해야 하기 때문입니다. 예를 들면 다음과 같습니다.</p>
+
+<pre>
+&lt;activity android:name="ShareActivity">
+ &lt;!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.SENDTO"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:scheme="sms" />
+ &lt;data android:scheme="smsto" />
+ &lt;/intent-filter>
+ &lt;!-- filter for sending text or images; accepts SEND action and text or image data -->
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.SEND"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:mimeType="image/*"/>
+ &lt;data android:mimeType="text/plain"/>
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p class="note"><strong>참고:</strong> 암묵적인 인텐트를 수신하기 위해서는
+{@link android.content.Intent#CATEGORY_DEFAULT} 카테고리를 인텐트 필터에 포함해야 합니다. {@link
+android.app.Activity#startActivity startActivity()} 및 {@link
+android.app.Activity#startActivityForResult startActivityForResult()} 메서드는 {@link android.content.Intent#CATEGORY_DEFAULT} 카테고리를
+선언한 것으로 모든 인텐트를 간주합니다. 인텐트 필터에서 이 카테고리를
+선언하지 않으면 어떠한 암묵적인 인텐트도 액티비티로 확인되지 않습니다.</p>
+
+<p>소셜 공유 동작을 수행하는 {@link android.content.Intent#ACTION_SEND}
+인텐트의 송수신에 대한 자세한 내용은 <a href="{@docRoot}training/sharing/receive.html">다른 앱에서 간단한 데이터 수신하기</a> 과정을 참조하세요.</p>
+
+
+<h2 id="HandleIntent">액티비티에서 인텐트 처리하기</h2>
+
+<p>액티비티를 시작하는 데 사용된 {@link
+android.content.Intent}를 읽어 액티비티에서 취할 작업을 결정할 수 있습니다.</p>
+
+<p>액티비티가 시작되면, {@link android.app.Activity#getIntent()}를 호출하여
+액티비티를 시작한 {@link android.content.Intent}를 검색합니다. 이 작업은 액티비티의
+수명 주기 동안 언제든지 가능하지만, 일반적으로
+{@link android.app.Activity#onCreate onCreate()} 또는 {@link android.app.Activity#onStart()}와 같은 초기 콜백 과정에서 수행합니다.</p>
+
+<p>예를 들면 다음과 같습니다.</p>
+
+<pre>
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.main);
+
+ // Get the intent that started this activity
+ Intent intent = getIntent();
+ Uri data = intent.getData();
+
+ // Figure out what to do based on the intent type
+ if (intent.getType().indexOf("image/") != -1) {
+ // Handle intents with image data ...
+ } else if (intent.getType().equals("text/plain")) {
+ // Handle intents with text ...
+ }
+}
+</pre>
+
+
+<h2 id="ReturnResult">결과 반환하기</h2>
+
+<p>액티비티를 호출한 액티비티로 결과를 반환하고자 하는 경우, 간단하게 {@link
+android.app.Activity#setResult(int,Intent) setResult()}를 호출하여 결과 코드 및 결과 {@link
+android.content.Intent}를 지정하면 됩니다. 작업이 끝나고 사용자가 원래
+액티비티로 되돌아갈 경우, {@link android.app.Activity#finish()}를 호출하여 액티비티를 종료(및 소멸)합니다. 예를 들면
+다음과 같습니다.</p>
+
+<pre>
+// Create intent to deliver some kind of result data
+Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");
+setResult(Activity.RESULT_OK, result);
+finish();
+</pre>
+
+<p>결과 코드는 항상 결과와 함께 지정해야 합니다. 일반적으로 {@link
+android.app.Activity#RESULT_OK} 또는 {@link android.app.Activity#RESULT_CANCELED}입니다. 그런 다음 필요한 경우 {@link android.content.Intent}를 사용하여 추가 데이터를
+제공할 수 있습니다.</p>
+
+<p class="note"><strong>참고:</strong> 결과는 기본적으로 {@link
+android.app.Activity#RESULT_CANCELED}로 설정됩니다. 따라서 작업을 완료하기 전과
+개발자가 결과를 설정하기 전에 사용자가 <em>뒤로</em> 버튼을 누를 경우, 원래의 액티비티는
+"취소" 결과를 받게 됩니다.</p>
+
+<p>단순히 여러 가지 결과 옵션 중 하나를 나타내는 정수만 반환하면 되는 경우,
+결과 코드를 0보다 큰 임의의 값으로 설정하면 됩니다. 결과 코드를 사용하여 정수만 제공하고
+{@link android.content.Intent}를 포함할 필요는 없는 경우, {@link
+android.app.Activity#setResult(int) setResult()}를 호출하고 결과 코드만 전달하면 됩니다. 예를 들면 다음과 같습니다.</p>
+
+<pre>
+setResult(RESULT_COLOR_RED);
+finish();
+</pre>
+
+<p>이런 경우, 가능한 결과는 몇 개에 불과할 것이므로 결과 코드는 로컬로
+정의된 정수입니다(0보다 큼). 이는 자신의 앱에서 액티비티에 결과를 반환할 때
+유용합니다. 왜냐하면 결과를 수신한 액티비티가 공용 상수를 참조하여 결과 코드의
+값을 확인할 수 있기 때문입니다.</p>
+
+<p class="note"><strong>참고:</strong> {@link android.app.Activity#startActivity startActivity()}
+또는 {@link
+android.app.Activity#startActivityForResult startActivityForResult()}로 액티비티가
+시작되었는지 확인할 필요는 없습니다. 액티비티를 시작한
+인텐트가 결과를 원할 경우, {@link android.app.Activity#setResult(int,Intent) setResult()}를
+호출하기만 하면 됩니다. 원래의 액티비티가 {@link
+android.app.Activity#startActivityForResult startActivityForResult()}를 호출한 경우, 시스템은 개발자가 {@link android.app.Activity#setResult(int,Intent) setResult()}에 제공하는
+결과를 액티비티에 제공합니다. 그렇지 않을 경우
+결과는 무시됩니다.</p>
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/ko/training/basics/intents/index.jd b/docs/html-intl/intl/ko/training/basics/intents/index.jd
new file mode 100644
index 0000000..d4aa0cb
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/basics/intents/index.jd
@@ -0,0 +1,62 @@
+page.title=다른 앱과 상호 작용하기
+page.tags=intents,activity
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>종속관계 및 전제조건</h2>
+<ul>
+ <li>액티비티 수명 주기에 대한 기본 지식(<a href="{@docRoot}training/basics/activity-lifecycle/index.html">액티비티
+수명 주기 관리하기</a> 참조)</li>
+</ul>
+
+
+<h2>필독 항목</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">간단한 데이터 공유하기</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">파일 공유하기</a>
+ <li><a href="http://android-developers.blogspot.com/2009/11/integrating-application-with-intents.html">
+인텐트와 애플리케이션 통합하기(블로그 게시물)</a></li>
+ <li><a href="{@docRoot}guide/components/intents-filters.html">인텐트 및 인텐트
+필터</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>Android 앱은 보통 여러 <a href="{@docRoot}guide/components/activities.html">액티비티</a>를 가지고 있습니다. 각 액티비티는
+사용자가 지도 보기 및 사진 촬영과 같은 특정 작업을 수행할 수 있게 해주는 사용자 인터페이스를 표시합니다.
+사용자가 하나의 액티비티에서 다른 액티비티로 전환되도록 하려면 {@link
+android.content.Intent}를 사용하여 앱의 "인텐트"가 어떠한 작업을 하도록 정의해야 합니다. {@link
+android.app.Activity#startActivity startActivity()}와 같은 메서드로 시스템에
+{@link android.content.Intent}를 전달하면, 시스템은 {@link
+android.content.Intent}를 사용하여 적절한 앱 구성요소를 식별하고 시작합니다. 인텐트를 사용하면
+자신의 앱에서 별도의 앱에 포함된 액티비티를 시작하도록 할 수 있습니다.</p>
+
+<p>{@link android.content.Intent}는 특정
+구성요소(특정 {@link android.app.Activity} 인스턴스)를 시작하기 위한 <em>명시적인 인텐트</em>이거나, "사진 캡처"와 같은 의도된 작업을 처리할 수 있는
+임의의 구성요소를 시작하기 위한 <em>암묵적인 인텐트</em>일 수 있습니다.</p>
+
+<p>이 클래스에서는 {@link android.content.Intent}를 사용하여 다른 앱과 몇 가지 기본적인
+상호 작용을 수행하는 방법을 보여줍니다. 이러한 상호 작용에는 다른 앱 시작, 해당 앱에서 결과 수신하기,
+다른 앱의 인텐트에 응답할 수 있도록 앱 구성하기 등이 있습니다.</p>
+
+<h2>과정</h2>
+
+<dl>
+ <dt><b><a href="sending.html">다른 앱으로 사용자 보내기</a></b></dt>
+ <dd>작업을 수행할 수 있는 다른 앱을 시작하기 위한
+암묵적인 인텐트를 생성하는 방법을 보여줍니다.</dd>
+ <dt><b><a href="result.html">액티비티로부터 결과 가져오기</a></b></dt>
+ <dd>다른 액티비티를 시작하고 해당 액티비티로부터 결과를 수신하는 방법을 보여줍니다.</dd>
+ <dt><b><a href="filters.html">다른 앱이 자신의 액티비티를 시작하도록 허용하기</a></b></dt>
+ <dd>앱이 수락하는 암묵적인 인텐트를 선언하는
+인텐트 필터를 정의하여 자신의 앱의 액티비티를 다른 앱이 사용할 수 있도록 공개하는 방법을 보여줍니다.</dd>
+</dl>
+
diff --git a/docs/html-intl/intl/ko/training/basics/intents/result.jd b/docs/html-intl/intl/ko/training/basics/intents/result.jd
new file mode 100644
index 0000000..7b25eaf8
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/basics/intents/result.jd
@@ -0,0 +1,178 @@
+page.title=액티비티로부터 결과 가져오기
+page.tags=intents
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>이 과정에서 다루는 내용</h2>
+<ol>
+ <li><a href="#StartActivity">액티비티 시작하기</a></li>
+ <li><a href="#ReceiveResult">결과 수신하기</a></li>
+</ol>
+
+<h2>필독 항목</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">간단한 데이터 공유하기</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">파일 공유하기</a>
+</ul>
+
+ </div>
+</div>
+
+<p>다른 액티비티를 시작하는 것이 단방향일 필요는 없습니다. 다른 액티비티를 시작하고 그 액티비티로부터 결과를
+수신할 수도 있습니다. 결과를 수신하려면 {@link android.app.Activity#startActivityForResult
+startActivityForResult()}를 호출합니다({@link android.app.Activity#startActivity
+startActivity()} 대신).</p>
+
+<p>예를 들어 자신의 앱에서 카메라 앱을 시작하고, 그 결과로 캡처된 사진을 수신할 수 있습니다. 또는,
+피플 앱을 시작하여 사용자가 연락처를 선택할 수 있도록 할
+수 있으며, 그 결과로 연락처 상세정보를 수신할 수 있습니다.</p>
+
+<p>물론, 응답하는 액티비티는 결과를 반환하도록 설계되어 있어야 합니다. 그럴 경우, 이 액티비티는
+또 다른 {@link android.content.Intent} 개체의 형태로 결과를 전송합니다. 그러면 액티비티가 {@link android.app.Activity#onActivityResult onActivityResult()} 콜백으로
+이 결과를 수신합니다.</p>
+
+<p class="note"><strong>참고:</strong> {@link android.app.Activity#startActivityForResult startActivityForResult()}를
+호출할 때 명시적 또는 암묵적인 인텐트를 사용할 수 있습니다. 자신이 정의한 액티비티 중
+하나를 시작하여 결과를 수신하는 경우 예상하는 결과를 수신하도록 보장하려면 명시적인 인텐트를
+사용해야 합니다.</p>
+
+
+<h2 id="StartActivity">액티비티 시작하기</h2>
+
+<p>결과를 수신하기 위해 액티비티를 시작할 때 사용하는 {@link android.content.Intent} 개체와
+관련하여 특별한 사항은 없습니다. 하지만, {@link
+android.app.Activity#startActivityForResult startActivityForResult()} 메서드에 추가적인 정수 인수를 전달해야 합니다.</p>
+
+<p>정수 인수는 요청을 식별하는 "요청 코드"입니다. 결과 {@link android.content.Intent}를
+수신하는 경우, 앱이 결과를 올바르게 식별하여 이를 처리할 방법을 결정할 수
+있도록 콜백이 이와 똑같은 요청 코드를 제공합니다.</p>
+
+<p>다음은 사용자가 연락처를 선택할 수 있게 하는 액티비티를 시작하는 방법에 대한 예제입니다.</p>
+
+<pre>
+static final int PICK_CONTACT_REQUEST = 1; // The request code
+...
+private void pickContact() {
+ Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
+ pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
+ startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
+}
+</pre>
+
+
+<h2 id="ReceiveResult">결과 수신하기</h2>
+
+<p>사용자가 후속 액티비티 작업을 마치고 돌아오면, 시스템은 개발자 자신이 정의한 원래 액티비티의
+{@link android.app.Activity#onActivityResult onActivityResult()} 메서드를 호출합니다. 이 메서드는 다음 세 가지
+인수를 포함합니다.</p>
+
+<ul>
+ <li>{@link
+android.app.Activity#startActivityForResult startActivityForResult()}에 전달한 요청 코드</li>
+ <li>두 번째 액티비티가 지정한 결과 코드. 이 코드는 작업이 성공한 경우 {@link
+android.app.Activity#RESULT_OK}이고, 사용자가 작업을 취소했거나 작업이 어떠한
+이유로 실패한 경우 {@link
+android.app.Activity#RESULT_CANCELED}입니다.</li>
+ <li>결과 데이터를 전달하는 {@link android.content.Intent}</li>
+</ul>
+
+<p>다음은 "연락처 선택하기" 인텐트에 대한 결과를 처리하는 방법을 보여주는 예제입니다.</p>
+
+<pre>
+&#64;Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // Check which request we're responding to
+ if (requestCode == PICK_CONTACT_REQUEST) {
+ // Make sure the request was successful
+ if (resultCode == RESULT_OK) {
+ // The user picked a contact.
+ // The Intent's data Uri identifies which contact was selected.
+
+ // Do something with the contact here (bigger example below)
+ }
+ }
+}
+</pre>
+
+<p>이 예제에서는 Android 연락처 또는 피플 앱에서
+반환되는 결과 {@link android.content.Intent}가 사용자가 선택한 연락처를 식별하는 {@link android.net.Uri} 콘텐츠를
+제공합니다.</p>
+
+<p>결과를 성공적으로 처리하기 위해서는
+결과 {@link android.content.Intent}의 형식이 무엇인지 이해하고 있어야 합니다. 결과를 반환하는 액티비티가 자신이 정의한 액티비티 중
+하나일 경우, 그 결과를 이해하기가 쉽습니다. Android 플랫폼에 포함된 앱은 특정한 결과 데이터를 기대할 수
+있는 고유한 API를 제공합니다. 예를 들어, 피플 앱(일부 이전 버전의 경우
+연락처 앱)은 선택된 연락처를 식별하는 콘텐츠 URI와 함께 항상 결과를 반환합니다. 또한
+카메라 앱은 {@code "data"} 엑스트라에 {@link android.graphics.Bitmap}을 반환합니다(<a href="{@docRoot}training/camera/index.html">사진 캡처하기</a>
+클래스 참조).</p>
+
+
+<h4>보너스: 연락처 데이터 읽기</h4>
+
+<p>피플 앱에서 결과를 가져오는 방법을 보여주는 상기 코드는, 결과에서
+데이터를 실제로 읽는 방법에 대해 구체적으로 설명하지는 않습니다. 그 이유는 이를 설명하려면
+<a href="{@docRoot}guide/topics/providers/content-providers.html">콘텐츠 제공자</a>에 대한 심도 있는 논의가
+필요하기 때문입니다. 하지만 이러한 내용이 궁금할 경우, 결과 데이터를 쿼리하여 선택된
+연락처에서 전화번호를 가져오는 방법을 보여주는 다음 코드를 참조하세요.</p>
+
+<pre>
+&#64;Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // Check which request it is that we're responding to
+ if (requestCode == PICK_CONTACT_REQUEST) {
+ // Make sure the request was successful
+ if (resultCode == RESULT_OK) {
+ // Get the URI that points to the selected contact
+ Uri contactUri = data.getData();
+ // We only need the NUMBER column, because there will be only one row in the result
+ String[] projection = {Phone.NUMBER};
+
+ // Perform the query on the contact to get the NUMBER column
+ // We don't need a selection or sort order (there's only one result for the given URI)
+ // CAUTION: The query() method should be called from a separate thread to avoid blocking
+ // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
+ // Consider using {@link android.content.CursorLoader} to perform the query.
+ Cursor cursor = getContentResolver()
+ .query(contactUri, projection, null, null, null);
+ cursor.moveToFirst();
+
+ // Retrieve the phone number from the NUMBER column
+ int column = cursor.getColumnIndex(Phone.NUMBER);
+ String number = cursor.getString(column);
+
+ // Do something with the phone number...
+ }
+ }
+}
+</pre>
+
+<p class="note"><strong>참고:</strong> Android 2.3(API 레벨 9) 이전에서는 위에 표시된 코드와
+같이 {@link android.provider.ContactsContract.Contacts Contacts Provider}에 대해 쿼리를
+수행하려면 앱에서 {@link
+android.Manifest.permission#READ_CONTACTS} 권한을 선언해야 합니다(<a href="{@docRoot}guide/topics/security/security.html">보안 및 권한</a> 참조). 하지만
+Android 2.3부터는 연락처 제공자가 결과를 반환할 때 자신의 앱에서
+그 결과를 읽어올 수 있도록 연락처/피플 앱이 임시 권한을 부여합니다. 임시 권한은 해당 연락처 요청에만
+적용되기 때문에, 인텐트의 {@link android.net.Uri}에
+지정된 연락처 외에는 쿼리할 수 없습니다. 다만, {@link
+android.Manifest.permission#READ_CONTACTS} 권한을 명시적으로 선언한 경우는 예외입니다.</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/ko/training/basics/intents/sending.jd b/docs/html-intl/intl/ko/training/basics/intents/sending.jd
new file mode 100644
index 0000000..b3e84eb
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/basics/intents/sending.jd
@@ -0,0 +1,256 @@
+page.title=다른 앱으로 사용자 보내기
+page.tags=intents
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>이 과정에서 다루는 내용</h2>
+<ol>
+ <li><a href="#Build">암묵적인 인텐트 구축하기</a></li>
+ <li><a href="#Verify">인텐트를 수신할 앱이 있는지 확인하기</a></li>
+ <li><a href="#StartActivity">인텐트를 사용하여 액티비티 시작하기</a></li>
+ <li><a href="#AppChooser">앱 선택기 표시하기</a></li>
+</ol>
+
+<h2>필독 항목</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">간단한 데이터 공유하기</a></li>
+</ul>
+
+ </div>
+</div>
+
+<p>Android의 가장 중요한 특징 중 하나는 수행하고자 하는 "작업"을
+기반으로 사용자를 다른 앱으로 보낼 수 있는 앱의 기능입니다. 예를 들어
+지도에 나타내고자 하는 사업체의 주소가 앱에 있는 경우, 지도를 보여주는 액티비티를 앱 내에
+구축할 필요가 없습니다. 대신 {@link android.content.Intent}를
+사용하여 주소 보기 요청을 생성할 수 있습니다. 그러면 Android 시스템이 지도에
+주소를 표시할 수 있는 앱을 시작합니다.</p>
+
+<p>첫 번째 클래스인 <a href="{@docRoot}training/basics/firstapp/index.html">첫
+앱 구축</a>에서 설명했듯이, 인텐트를 사용하여 자체 앱 내에서 액티비티 간을 탐색해야 합니다. 일반적으로
+시작하고자 하는
+구성요소의 정확한 클래스 이름을 정의하는 <em>명시적인 인텐트</em>를 사용하여 이러한 작업을 수행합니다. 하지만 "지도 보기"와
+같은 작업을 별도의 앱에서 수행하도록 하기를 원할 경우, <em>암묵적인 인텐트</em>를 사용해야 합니다.</p>
+
+<p>이 과정에서는 특정 작업에 대한 암묵적인 인텐트를 생성하는 방법과 이를 사용하여
+다른 앱에서 작업을 수행하는 액티비티를 시작하는 방법에 대해 설명합니다.</p>
+
+
+
+<h2 id="Build">암묵적인 인텐트 구축하기</h2>
+
+<p>암묵적인 인텐트는 시작할 구성요소의 클래스 이름을 선언하지 않고, 그 대신 수행할
+작업을 선언합니다. 작업은 <em>보기</em>,
+<em>편집하기</em>, <em>보내기</em> 또는 <em>가져오기</em>와 같이 수행하고자 하는 동작을 지정합니다. 또한 인텐트는 보기 원하는 주소, 또는 전송하기 원하는 이메일 메시지와 같이 작업과
+연결된 데이터를 함께 포함하는 경우가 많습니다.
+생성하고자 하는 인텐트에 따라 데이터는 {@link android.net.Uri}이거나
+다른 여러 가지 데이터 유형 중 하나일 수 있으며, 인텐트가 데이터를 전혀 필요로 하지 않을 수도 있습니다.</p>
+
+<p>데이터가 {@link android.net.Uri}인 경우, 간단한 {@link
+android.content.Intent#Intent(String,Uri) Intent()} 생성자를 사용하여 액션 및
+데이터를 정의할 수 있습니다.</p>
+
+<p>다음은 {@link
+android.net.Uri} 데이터를 사용하여 전화번호를 지정하여 전화 걸기를 시작하는 인텐트를 생성하는 방법입니다.</p>
+
+<pre>
+Uri number = Uri.parse("tel:5551234");
+Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
+</pre>
+
+<p>앱이 {@link android.app.Activity#startActivity
+startActivity()}를 호출하여 이 인텐트를 호출하면, 전화 앱이 주어진 전화번호로 전화를 겁니다.</p>
+
+<p>다음은 몇 가지 다른 인텐트와 해당 작업 및 {@link android.net.Uri} 데이터
+쌍입니다.</p>
+
+<ul>
+ <li>지도 보기:
+<pre>
+// Map point based on address
+Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
+// Or map point based on latitude/longitude
+// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
+Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
+</pre>
+ </li>
+ <li>웹 페이지 보기:
+<pre>
+Uri webpage = Uri.parse("http://www.android.com");
+Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
+</pre>
+ </li>
+</ul>
+
+<p>다른 종류의 암묵적인 인텐트는 문자열과 같이
+여러 데이터 유형을 제공하는 "엑스트라" 데이터를 필요로 합니다. 다양한 {@link
+android.content.Intent#putExtra(String,String) putExtra()} 메서드를 사용하여 하나 이상의 엑스트라 데이터를 추가할 수 있습니다.</p>
+
+<p>기본적으로 시스템은 포함된
+{@link android.net.Uri} 데이터를 바탕으로 인텐트가 필요로 하는 적절한 MIME 유형을 결정합니다. {@link android.net.Uri}를 인텐트에
+포함하지 않을 경우, 일반적으로 {@link android.content.Intent#setType setType()}을 사용하여 인텐트와 관련된 데이터의
+유형을 지정해야 합니다. MME 유형을 설정하면 인텐트를 수신할
+액티비티의 종류도 지정됩니다.</p>
+
+<p>다음은 원하는 작업을 지정하기 위해 엑스트라 데이터를 추가하는 인텐트의 몇 가지 예제입니다.</p>
+
+<ul>
+ <li>첨부 파일과 함께 이메일 보내기:
+<pre>
+Intent emailIntent = new Intent(Intent.ACTION_SEND);
+// The intent does not have a URI, so declare the "text/plain" MIME type
+emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
+emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients
+emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
+emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
+emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));
+// You can also attach multiple items by passing an ArrayList of Uris
+</pre>
+ </li>
+ <li>캘린더 이벤트 생성하기:
+<pre>
+Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
+Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);
+Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);
+calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
+calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
+calendarIntent.putExtra(Events.TITLE, "Ninja class");
+calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");
+</pre>
+<p class="note"><strong>참고:</strong> 캘린더 이벤트에 대한 이 인텐트는 API
+레벨 14 이상에서만 지원됩니다.</p>
+ </li>
+</ul>
+
+<p class="note"><strong>참고:</strong> {@link
+android.content.Intent}는 되도록 구체적으로 정의해야 합니다. 예를 들어 {@link android.content.Intent#ACTION_VIEW} 인텐트를
+사용하여 이미지를 표시하고자 할 경우,
+{@code image/*}의 MIME 유형을 지정해야 합니다. 그러면 지도 앱과 같이 다른 유형의 데이터를 "볼" 수 있는 앱이 인텐트에 의해
+트리거되는 것이 방지됩니다.</p>
+
+
+
+<h2 id="Verify">인텐트를 수신할 앱이 있는지 확인하기</h2>
+
+<p>Android 플랫폼은 전화, 이메일 또는 캘린더 앱과 같은
+내장 앱 중 하나로 특정 인텐트가 처리되도록 보장하지만, 인텐트를 호출하기 전에 항상
+확인 단계를 포함하는 것이 좋습니다.</p>
+
+<p class="caution"><strong>주의:</strong> 인텐트를 호출한 후 해당 인텐트를 처리할 수 있는 앱이
+기기에 없을 경우, 앱은 작동을 중단합니다.</p>
+
+<p>인텐트에 응답할 수 있는 액티비티가 있는지 확인하려면 {@link
+android.content.pm.PackageManager#queryIntentActivities queryIntentActivities()}를 호출하여 {@link android.content.Intent}를 처리할 수 있는 액티비티
+목록을 가져와야 합니다. 반환된 {@link
+java.util.List}가 비어있지 않을 경우, 안심하고 인텐트를 사용할 수 있습니다. 예를 들면 다음과 같습니다.</p>
+
+<pre>
+PackageManager packageManager = {@link android.content.Context#getPackageManager()};
+List<ResolveInfo> activities = packageManager.queryIntentActivities(intent,
+ PackageManager.MATCH_DEFAULT_ONLY);
+boolean isIntentSafe = activities.size() > 0;
+</pre>
+
+<p><code>isIntentSafe</code>가 <code>true</code>일 경우, 하나 이상의 앱이
+인텐트에 응답합니다. <code>false</code>일 경우, 인텐트를 처리할 수 있는 앱이 없는 것입니다.</p>
+
+<p class="note"><strong>참고:</strong> 사용자가 인텐트를
+사용하려고 하기 전에 이 인텐트를 사용하는 기능을 해제해야 할 경우, 액티비티가 처음
+시작될 때 이 확인 작업을 수행해야 합니다. 인텐트를 처리할 수 있는 앱을 알고 있을 경우,
+사용자가 앱을 다운로드할 수 있도록 링크를 제공할 수도 있습니다(<a href="{@docRoot}distribute/tools/promote/linking.html">Google
+Play에서 자신의 제품에 대한 링크를 제공</a>하는 방법 참조).</p>
+
+
+<h2 id="StartActivity">인텐트를 사용하여 액티비티 시작하기</h2>
+
+<div class="figure" style="width:200px;margin-top:-10px">
+ <img src="{@docRoot}images/training/basics/intents-choice.png" alt="" />
+ <p class="img-caption"><strong>그림 1.</strong> 인텐트를 처리할 수 있는 앱이 둘 이상 있을 경우 표시되는 선택 대화 상자의 예.
+</p>
+</div>
+
+<p>{@link android.content.Intent}를 생성하고 엑스트라 정보를 설정한 후에는 {@link
+android.app.Activity#startActivity startActivity()}를 호출하여 시스템에 보내야 합니다. 시스템이 인텐트를 처리할 수 있는 액티비티를 둘 이상
+식별하는 경우, 그림 1과 같이 사용자가 사용할 앱을
+선택할 수 있는 대화 상자를 표시합니다. 인텐트를
+처리할 수 있는 액티비티가 하나밖에 없을 경우, 시스템이 해당 액티비티를 바로 시작합니다.</p>
+
+<pre>
+startActivity(intent);
+</pre>
+
+<p>다음은 지도 보기 인텐트를 생성하고, 인텐트를 처리할 수 있는
+앱의 존재 여부를 확인하고, 앱을 시작하는 방법을 보여주는 완벽한 예제입니다.</p>
+
+<pre>
+// Build the intent
+Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
+Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
+
+// Verify it resolves
+PackageManager packageManager = {@link android.content.Context#getPackageManager()};
+List&lt;ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
+boolean isIntentSafe = activities.size() > 0;
+
+// Start an activity if it's safe
+if (isIntentSafe) {
+ startActivity(mapIntent);
+}
+</pre>
+
+
+
+<h2 id="AppChooser">앱 선택기 표시하기</h2>
+
+<div class="figure" style="width:200px;margin-top:-10px">
+ <img src="{@docRoot}images/training/basics/intent-chooser.png" alt="" />
+ <p class="img-caption"><strong>그림 2.</strong> 선택기 대화 상자.</p>
+</div>
+
+<p>{@link android.content.Intent}를 {@link
+android.app.Activity#startActivity startActivity()}에 전달하여 액티비티를 시작하는데 인텐트에
+응답하는 앱이 둘 이상 있는 경우, 사용자는 어떤 앱을 기본으로 사용할지 선택할 수 있습니다(이는 대화 상자
+하단의 확인란을 선택하여 수행할 수 있음. 그림 1 참조). 이는 사용자가 일반적으로
+항상 동일한 앱을 사용하기 원하는 작업을 수행하는 경우에 유용합니다. 예를 들어 웹 페이지를 열 때(사용자는
+대개 하나의 웹 브라우저를 사용함) 또는 사진을 찍을 때(사용자는 대개 하나의 카메라를 선호함) 등이 있습니다.</p>
+
+<p>하지만 "공유" 작업과 같이 항목을 공유할 앱을
+여러 개 보유하고 있는 경우처럼, 수행할 작업을 처리할 수 있는 앱이 여러 개 있고 사용자가 매번 다른 앱을
+원할 수도 있습니다. 이런 경우, 그림 2와 같이
+선택기 대화 상자를 명시적으로 표시합니다. 선택기 대화 상자는
+사용자가 작업에 사용할 앱을 매번 선택하도록 합니다(사용자는 작업에 사용할
+기본 앱을 선택할 수 없음).</p>
+
+<p>선택기를 표시하려면 {@link
+android.content.Intent#createChooser createChooser()}를 사용하여 {@link android.content.Intent}를 생성한 후 {@link
+android.app.Activity#startActivity startActivity()}에 전달합니다. 예를 들면 다음과 같습니다.</p>
+
+<pre>
+Intent intent = 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 chooser
+Intent chooser = Intent.createChooser(intent, title);
+
+// Verify the intent will resolve to at least one activity
+if (intent.resolveActivity(getPackageManager()) != null) {
+ startActivity(chooser);
+}
+</pre>
+
+<p>이 예제는 {@link
+android.content.Intent#createChooser createChooser()} 메서드에 전달된 인텐트에 응답하는 앱 목록이 포함된 대화 상자를 표시하고 제공된 텍스트를
+대화 상자 제목으로 사용합니다.</p>
+
+
+
diff --git a/docs/html-intl/intl/pt-br/design/get-started/principles.jd b/docs/html-intl/intl/pt-br/design/get-started/principles.jd
new file mode 100644
index 0000000..46af758
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/design/get-started/principles.jd
@@ -0,0 +1,307 @@
+page.title=Princípios de projeto para Android
+@jd:body
+
+<p>Estes princípios de projeto foram desenvolvidos pela e para a Equipe de Experiência do Usuário do Android
+para manter os interesses dos usuários em mente.
+Para desenvolvedores e projetistas do Android, eles continuam a
+definir as diretrizes de projeto mais detalhadas para diferentes
+tipos de dispositivo.</p>
+
+<p>
+Considere estes princípios ao aplicar
+suas próprias criatividade e mentalidade de projeto. Desvie-se de forma objetiva.
+</p>
+
+<h2 id="enchant-me">Encante-me</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="delight-me">Agrade-me de formas surpreendentes</h4>
+<p>Uma bela superfície, uma animação cuidadosamente posicionada ou um efeito sonoro no momento certo
+ contribui para a boa experiência. Efeitos sutis contribuem para uma sensação de facilidade e de que algo
+poderoso está à mão.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_delight.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="real-objects-more-fun">Objetos reais são mais divertidos que botões e menus</h4>
+<p>Deixe que as pessoas manipulem e toquem diretamente em objetos no seu aplicativo. Isso reduz o esforço cognitivo
+necessário para realizar uma tarefa e torna o aplicativo mais emocionalmente satisfatório.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_real_objects.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="make-it-mine">Deixe-me torná-lo meu</h4>
+<p>As pessoas adoram adicionar toques pessoais, pois isso as ajuda a se sentirem à vontade e em controle. Forneça
+padrões sensatos e belos, mas também considere personalizações divertidas e opcionais que não
+prejudiquem as tarefas principais.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_make_it_mine.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="get-to-know-me">Conheça-me</h4>
+<p>Conheça as preferências das pessoas no decorrer do tempo. Em vez de pedir que façam as mesmas escolhas repetidamente,
+coloque escolhas anteriores em alcance fácil.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_get_to_know_me.png">
+
+ </div>
+</div>
+
+<h2 id="simplify-my-life">Simplifique minha vida</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="keep-it-brief">Seja breve</h4>
+<p>Use frases curtas com palavras simples. As pessoas provavelmente ignorarão frases longas.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_keep_it_brief.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="pictures-faster-than-words">Imagens são mais rápidas que palavras</h4>
+<p>Considere usar imagens para explicar ideias. Elas chamam a atenção das pessoas e podem ser muito mais eficientes
+que palavras.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_pictures.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="decide-for-me">Decida por mim, mas deixe que eu tenha a palavra final</h4>
+<p>Faça a melhor suposição e tome uma ação, em vez de primeiro perguntar. Escolhas e decisões demais deixam as pessoas
+incomodadas. Caso suponha errado, permita "desfazer".</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_decide_for_me.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="only-show-when-i-need-it">Mostre só o que preciso, quando eu precisar</h4>
+<p>As pessoas se sentem oprimidas quando veem coisas demais de uma vez. Detalhe tarefas e informações em partes
+pequenas e digeríveis. Oculte opções que não sejam essenciais no momento e ensine as pessoas à medida que avançam.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_information_when_need_it.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="always-know-where-i-am">Eu sempre devo saber onde estou</h4>
+<p>Dê às pessoas a confiança de saberem o que fazer. Faça com que os locais no seu aplicativo pareçam distintos
+e use transições para mostrar relacionamentos entre telas. Forneça feedback sobre tarefas em andamento.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_navigation.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="never-lose-my-stuff">Nunca perca as minhas coisas</h4>
+<p>Salve o que as pessoas criaram e deixe que elas acessem de qualquer lugar. Lembre-se de configurações,
+toques pessoais e criações entre celulares, tablets e computadores. Isso torna a atualização a
+coisa mais fácil do mundo.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_never_lose_stuff.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="looks-same-should-act-same">Se parece igual, deve agir da mesma forma</h4>
+<p>Ajude as pessoas a discernir diferenças funcionais tornando-as visualmente distintas, em vez de sutis.
+Evite que modos locais que agem de forma diferente sobre a mesma entrada se pareçam.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_looks_same.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="interrupt-only-if-important">Só me interrompa se for importante</h4>
+<p>Como um bom assistente pessoal, proteja as pessoas de informações não importantes. As pessoas querem ficar
+concentradas e, a não ser que seja crítica e dependente de tempo, uma interrupção pode ser irritante e frustrante.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_important_interruption.png">
+
+ </div>
+</div>
+
+<h2 id="make-me-amazing">Faça com que eu seja incrível</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="give-me-tricks">Dê-me truques que funcionem em qualquer lugar</h4>
+<p>As pessoas se sentem ótimas quando descobrem coisas sozinhas. Torne seu aplicativo mais inteligível ao
+aproveitar padrões visuais e memórias de outros aplicativos do Android. Por exemplo, o gesto de deslizar
+pode ser um bom atalho de navegação.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_tricks.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="its-not-my-fault">Não é culpa minha</h4>
+<p>Seja gentil sobre como solicita correções a pessoas. Elas querem se sentir inteligentes ao usar o seu
+aplicativo. Se alguma coisa der errada, dê instruções de recuperação claras, mas evite os detalhes técnicos.
+Se for possível corrigir em segundo plano, melhor ainda.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_error.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="sprinkle-encouragement">Espalhe motivação</h4>
+<p>Divida tarefas complexas em passos menores que possam ser realizados facilmente. Dê feedback sobre ações,
+mesmo que seja um brilho sutil.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_sprinkle_encouragement.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="do-heavy-lifting-for-me">Faça o trabalho pesado por mim</h4>
+<p>Faça com que novatos se sintam peritos possibilitando que façam coisas que nunca acharam possíveis. Por
+exemplo, atalhos que combinem vários efeitos de fotos podem fazer com que fotografias amadoras pareçam incríveis
+com apenas alguns passos.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_heavy_lifting.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="make-important-things-fast">Torne coisas importantes rápidas</h4>
+<p>Nem todas as ações são iguais. Decida o que é mais importante em seu aplicativo e torne fácil de encontrar e
+rápido de usar, como o botão do obturador em uma câmera ou o botão de pausa em um reprodutor de música.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_make_important_fast.png">
+
+ </div>
+</div>
diff --git a/docs/html-intl/intl/pt-br/design/material/index.jd b/docs/html-intl/intl/pt-br/design/material/index.jd
new file mode 100644
index 0000000..60289a3
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/design/material/index.jd
@@ -0,0 +1,186 @@
+page.title=Material Design
+page.tags=Material,design
+page.type=design
+page.image=design/material/images/MaterialLight.png
+
+@jd:body
+
+<!-- developer docs box -->
+<a class="notice-developers right" href="{@docRoot}training/material/index.html">
+ <div>
+ <h3>Documentos do desenvolvedor</h3>
+ <p>Criação de aplicativos com o Material Design</p>
+ </div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw">
+<div>
+ <h3>Vídeo</h3>
+ <p>Introdução ao Material Design</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw">
+<div>
+ <h3>Vídeo</h3>
+ <p>Papel e tinta: Os materiais que importam</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc">
+<div>
+ <h3>Vídeo</h3>
+ <p>Material Design no aplicativo Google I/O</p>
+</div>
+</a>
+
+
+
+<p itemprop="description">O Material Design é um guia abrangente para design visual, de movimento e de
+interação para diversas plataformas e dispositivos. O Android agora é compatível com
+aplicativos do Material Design. Para usar o Material Design nos aplicativos Android, siga as orientações definidas
+nas <a href="http://www.google.com/design/spec">especificações do Material Design</a> e use os novos
+componentes e funcionalidades disponíveis no Android 5.0 (API de nível 21) e em posteriores.</p>
+
+<p>O Android fornece os seguintes elementos para criar aplicativos do Material Design:</p>
+
+<ul>
+ <li>Um novo tema</li>
+ <li>Novos widgets para vistas complexas</li>
+ <li>Novas APIs para sombras e animações personalizadas</li>
+</ul>
+
+<p>Para obter mais informações sobre a implementação do Material Design no Android, consulte
+<a href="{@docRoot}training/material/index.html">Criação de aplicativos com o Material Design</a>.</p>
+
+
+<h3>Tema do Material</h3>
+
+<p>O tema do Material fornece um novo estilo para o seu aplicativo, widgets de sistema que permitem
+definir a paleta de cores e as animações padrão para feedback de toque e transições de atividades.</p>
+
+<!-- two columns -->
+<div style="width:700px;margin-top:25px;margin-bottom:20px">
+<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">Tema escuro do Material</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">Tema claro do Material</p>
+ </div>
+</div>
+<br style="clear:left"/>
+</div>
+
+<p>Para obter mais informações, consulte <a href="{@docRoot}training/material/theme.html">Como usar o tema
+do Material</a>.</p>
+
+
+<h3>Listas e cartões</h3>
+
+<p>O Android fornece dois novos widgets para exibir cartões e listas com estilos e animações do
+Material Design:</p>
+
+<!-- two columns -->
+<div style="width:700px;margin-top:25px;margin-bottom:20px">
+<div style="float:left;width:250px;margin-left:40px;margin-right:60px;">
+ <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" />
+ <p>O novo widget <code>RecyclerView</code> é uma versão mais completa de <code>ListView</code>
+ com suporte para diferentes tipos de layout e melhorias no desempenho.</p>
+</div>
+<div style="float:left;width:250px;margin-right:0px;">
+ <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" />
+ <p>O novo widget <code>CardView</code> permite exibir informações importantes dentro de
+ cartões que têm aparência consistente.</p>
+</div>
+<br style="clear:left"/>
+</div>
+
+<p>Para obter mais informações, consulte <a href="{@docRoot}training/material/lists-cards.html">Como criar
+listas e cartões</a>.</p>
+
+
+<h3>Sombras de vistas</h3>
+
+<p>Além das propriedades X e Y, vistas no Android agora têm uma propriedade
+Z. Essa nova propriedade representa a elevação de uma vista, que determina:</p>
+
+<ul>
+<li>O tamanho da sombra: vistas com valores maiores de Z lançam sombras maiores.</li>
+<li>A ordem de desenho: vistas com valores maiores de Z aparecem sobre outras vistas.</li>
+</ul>
+
+<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/videos/ContactsAnim.webm"/>
+ <source src="{@docRoot}design/videos/ContactsAnim.ogv"/>
+ </video>
+ </div>
+ <div style="font-size:10pt;margin-left:20px;margin-bottom:30px">
+ <em>Para reproduzir o filme, clique na tela do dispositivo</em>
+ </div>
+</div>
+
+<p>Para obter mais informações, consulte <a href="{@docRoot}training/material/shadows-clipping.html">Como
+definir sombras e recortar visualizações</a>.</p>
+
+
+<h3>Animações</h3>
+
+<p>As novas APIs de animação permitem criar animações personalizadas para feedback de toque em controles de IU,
+mudanças no estado da vista e transições de atividades.</p>
+
+<p>Essas APIs permitem:</p>
+
+<ul>
+<li style="margin-bottom:15px">
+Responder a eventos de toque nas vistas com animações de <strong>feedback de toque</strong>.
+</li>
+<li style="margin-bottom:15px">
+Ocultar e exibir vistas com animações de <strong>revelação circular</strong>.
+</li>
+<li style="margin-bottom:15px">
+Alternar entre atividades com animações de <strong>transição de atividades</strong>.
+</li>
+<li style="margin-bottom:15px">
+Criar animações mais naturais com <strong>movimento curvado</strong>.
+</li>
+<li style="margin-bottom:15px">
+Animar mudanças em uma ou mais propriedades da vista com animações de <strong>mudança de estado da vista</strong>.
+</li>
+<li style="margin-bottom:15px">
+Exibir animações em <strong>desenháveis da lista de estado</strong> entre mudanças de estado da vista.
+</li>
+</ul>
+
+<p>Animações de feedback de toque são integradas em várias vistas padrões, como botões. As novas APIs
+permitem personalizar essas animações e adicioná-las às vistas personalizadas.</p>
+
+<p>Para obter mais informações, consulte <a href="{@docRoot}training/material/animations.html">Como definir
+animações personalizadas</a>.</p>
+
+
+<h3>Desenháveis</h3>
+
+<p>Essas novas capacidades dos desenháveis ajudam na implementação de aplicativos do Material Design:</p>
+
+<ul>
+<li><strong>Desenháveis de vetor</strong> são dimensionáveis sem perder definição e são perfeitos
+para ícones de uma cor dentro do aplicativo.</li>
+<li><strong>Tingimento desenhável</strong> permite definir mapas de bits como uma máscara alfa e tingi-los com
+uma cor em tempo de execução.</li>
+<li><strong>Extração de cor</strong> permite extrair automaticamente cores proeminentes de uma
+imagem de mapa de bits.</li>
+</ul>
+
+<p>Para obter mais informações, consulte <a href="{@docRoot}training/material/drawables.html">Como trabalhar
+com desenháveis</a>.</p>
diff --git a/docs/html-intl/intl/pt-br/design/patterns/confirming-acknowledging.jd b/docs/html-intl/intl/pt-br/design/patterns/confirming-acknowledging.jd
new file mode 100644
index 0000000..934dbdd
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/design/patterns/confirming-acknowledging.jd
@@ -0,0 +1,70 @@
+page.title=Confirmação e reconhecimento
+page.tags=dialog,toast,notification
+@jd:body
+
+<p>Em algumas situações, quando um usuário invoca uma ação em seu aplicativo, é uma boa ideia <em>confirmar</em> ou <em>reconhecer</em> essa ação com texto.</p>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-6">
+ <img src="{@docRoot}design/media/confirm_ack_confirming.png">
+ <p><strong>Confirmar</strong> é pedir ao usuário que verifique se realmente quer prosseguir com a ação que acabou de invocar. Em alguns casos, a confirmação é apresentada com uma advertência ou informações críticas relacionadas à ação que ele precisa considerar.</p>
+ </div>
+ <div class="layout-content-col span-6">
+ <img src="{@docRoot}design/media/confirm_ack_acknowledge.png">
+ <p><strong>Reconhecer</strong> é exibir texto para avisar ao usuário que a ação que acabou de ser invocada foi concluída. Isso remove a incerteza sobre operações implícitas que o sistema adota. Em alguns casos, o reconhecimento é apresentado com uma opção para desfazer a ação.</p>
+ </div>
+</div>
+
+<p>Comunicar-se com os usuários dessas formas pode ajudar a reduzir a incerteza sobre o que aconteceu ou o que acontecerá. Confirmar ou reconhecer também pode evitar que os usuários cometam erros dos quais possam se arrepender.</p>
+
+<h2>Quando confirmar ou reconhecer ações do usuário</h2>
+<p>Nem todas as ações precisam de uma confirmação ou um reconhecimento. Use este fluxograma para orientar as decisões de projeto.</p>
+<img src="{@docRoot}design/media/confirm_ack_flowchart.png">
+
+<h2>Confirmação</h2>
+<div class="layout-content-row">
+ <div class="layout-content-col span-6">
+ <h4>Exemplo: livros do Google Play</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_books.png">
+ <p>Nesse exemplo, o usuário solicitou a exclusão de um livro da biblioteca do Google Play. Um <a href="{@docRoot}design/building-blocks/dialogs.html#alerts">alerta</a> aparece para confirmar essa ação porque é importante entender que o livro não estará mais disponível em nenhum dispositivo.</p>
+ <p>Ao montar uma caixa de diálogo de confirmação, use um título significativo que ecoe a ação solicitada.</p>
+ </div>
+ <div class="layout-content-col span-7">
+ <h4>Exemplo: Android Beam</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_beam.png">
+ <p>As confirmações não necessariamente precisam ser apresentadas em um alerta com dois botões. Depois de iniciar o Android Beam, o usuário é solicitado a tocar no conteúdo a ser compartilhado (nesse exemplo, uma foto). Se ele decidir não prosseguir, simplesmente afastará o celular.</p>
+ </div>
+</div>
+
+<h2>Reconhecimento</h2>
+<div class="layout-content-row">
+ <div class="layout-content-col span-6">
+ <h4>Exemplo: abandonar rascunho salvo do Gmail</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_draftsave.png">
+ <p>Nesse exemplo, se o usuário navegar para trás ou para cima na tela de composição do Gmail, alguma coisa possivelmente inesperada acontecerá: o rascunho atual será salvo automaticamente. Um reconhecimento na forma de aviso torna isso aparente. Ele desaparece depois de alguns segundos.</p>
+ <p>Desfazer não é adequado aqui, pois o ato de salvar foi iniciado pelo aplicativo, não pelo usuário, Além de ser rápido e fácil retomar a composição da mensagem navegando para a lista de rascunhos.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+ <h4>Exemplo: conversa do Gmail excluída</h4>
+ <img src="{@docRoot}design/media/confirm_ack_draft_deleted.png">
+ <p>Depois que o usuário exclui uma conversa da lista no Gmail, um reconhecimento aparece com a opção de desfazer. O reconhecimento permanece até que o usuário tome uma ação não relacionada, como rolar a lista.</p>
+ </div>
+</div>
+
+<h2>Sem confirmação nem reconhecimento</h2>
+<div class="layout-content-row">
+ <div class="layout-content-col span-6">
+ <h4>Exemplo: +1</h4>
+ <img style="padding: 33px 0 30px;" src="{@docRoot}design/media/confirm_ack_ex_plus1.png">
+ <p><strong>A confirmação é desnecessária.</strong> Se o usuário usar +1 por acidente, não é um problema. Poderá simplesmente tocar no botão novamente para desfazer a ação.</p>
+ <p><strong>O reconhecimento é desnecessário.</strong> O usuário verá o botão +1 oscilar e ficar vermelho. Esse é um sinal muito claro.</p>
+ </div>
+ <div class="layout-content-col span-7">
+ <h4>Exemplo: Remover um aplicativo da tela inicial</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_removeapp.png">
+ <p><strong>A confirmação é desnecessária.</strong> Essa é uma ação deliberada: o usuário precisa arrastar e soltar um item em um alvo relativamente grande e isolado. Portanto, acidentes são altamente improváveis. Mas, se o usuário se arrepender da decisão, levará apenas alguns segundos para trazê-lo de volta.</p>
+ <p><strong>O reconhecimento é desnecessário.</strong> O usuário saberá que o aplicativo saiu da tela inicial porque fez com que ele desaparecesse arrastando-o para longe.</p>
+
+ </div>
+</div>
diff --git a/docs/html-intl/intl/pt-br/design/patterns/navigation.jd b/docs/html-intl/intl/pt-br/design/patterns/navigation.jd
new file mode 100644
index 0000000..920ccec
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/design/patterns/navigation.jd
@@ -0,0 +1,213 @@
+page.title=Navegação com Voltar e Para cima
+page.tags="navigation","activity","task","up navigation","back navigation"
+page.image=/design/media/navigation_between_siblings_gmail.png
+@jd:body
+
+<a class="notice-developers" href="{@docRoot}training/implementing-navigation/index.html">
+ <div>
+ <h3>Documentos do desenvolvedor</h3>
+ <p>Implementação de navegação efetiva</p>
+ </div>
+</a>
+
+<p itemprop="description">A navegação consistente é um componente essencial da experiência geral do usuário. Poucas coisas deixam os
+usuários mais frustrados do que uma navegação básica que se comporta de forma inconsistente ou inesperada. O Android 3.0
+introduziu mudanças significativas no comportamento global da navegação. Seguir cuidadosamente as
+diretrizes de Voltar e Para Cima tornará a navegação em seu aplicativo previsível e confiável para os usuários.</p>
+<p>O Android 2.3 e anteriores se baseavam no botão <em>Voltar</em> do sistema para dar suporte à navegação dentro de um
+aplicativo. Com a introdução de barras de ação no Android 3.0, um segundo mecanismo de navegação apareceu:
+o botão <em>Para Cima</em>, consistindo no ícone do aplicativo e em um cursor para a esquerda.</p>
+
+<img src="{@docRoot}design/media/navigation_with_back_and_up.png">
+
+<h2 id="up-vs-back">Para Cima vs. Voltar</h2>
+
+<p>O botão Para Cima é usado para navegar dentro de um aplicativo com base nos relacionamentos hierárquicos
+entre telas. Por exemplo, se a tela A exibe uma lista de itens e, selecionar um item leva à
+tela B (que apresenta aquele item em mais detalhes), então a tela B deve oferecer um botão Para Cima que
+volte à tela A.</p>
+<p>Se determinada tela é a superior na hierarquia de um aplicativo (ou seja, a página inicial do aplicativo), ela não deve apresentar um botão
+Para Cima.</p>
+
+<p>O botão Voltar do sistema é usado para navegar, em ordem cronológica inversa, pelo histórico
+de telas em que o usuário esteve recentemente. Ele é geralmente baseado em relacionamentos temporais
+entre telas, em vez de na hierarquia do aplicativo.</p>
+
+<p>Quando a tela visualizada anteriormente também for a superior hierárquica imediata da tela atual, pressionar
+o botão Voltar tem o mesmo resultado que pressionar um botão Para Cima &mdash; essa é uma ocorrência
+comum. No entanto, diferentemente do botão Para Cima, que garante que o usuário permaneça dentro do aplicativo, o botão
+Voltar pode retornar o usuário à tela inicial ou até mesmo a um aplicativo diferente.</p>
+
+<img src="{@docRoot}design/media/navigation_up_vs_back_gmail.png">
+
+<p>O botão Voltar também suporta alguns comportamentos não vinculados diretamente à navegação entre telas:
+</p>
+<ul>
+<li>Descarta janelas flutuantes (caixas de diálogo, pop-ups)</li>
+<li>Descarta barras de ação contextuais e remove o destaque dos itens selecionados</li>
+<li>Oculta o teclado da tela (IME)</li>
+</ul>
+<h2 id="within-app">Navegação dentro do seu aplicativo</h2>
+
+<h4>Navegação para telas com vários pontos de entrada</h4>
+<p>Algumas vezes, uma tela não tem uma posição estrita dentro da hierarquia do aplicativo e pode ser atingida
+de vários pontos de entrada &mdash; como uma tela de configurações que pode ser atingida de qualquer outra tela
+do aplicativo. Nesse caso, o botão Para Cima deve escolher voltar para a tela anterior, comportando-se
+de forma idêntica a Voltar.</p>
+<h4>Mudança de vista dentro de uma tela</h4>
+<p>Mudar opções de vista de uma tela não muda o comportamento de Para Cima nem de Voltar: a tela ainda
+estará no mesmo lugar dentro da hierarquia do aplicativo e nenhum histórico de navegação será criado.</p>
+<p>Exemplos de tais mudanças de vista são:</p>
+<ul>
+<li>Alternar vistas usando guias e/ou deslizando para a esquerda e para a direita</li>
+<li>Alternar vistas usando um menu suspenso (também chamados de abas recolhidas)</li>
+<li>Filtrar uma lista</li>
+<li>Classificar uma lista</li>
+<li>Mudar características de exibição (como mudar o zoom)</li>
+</ul>
+<h4>Navegação entre telas de mesmo nível</h4>
+<p>Quando o aplicativo suporta navegação de uma lista de itens para uma vista de detalhes de um desses itens,
+frequentemente é desejável dar suporte à navegação de direção daquele item para outro anterior ou
+posterior a ele na lista. Por exemplo, no Gmail, é fácil deslizar para a esquerda ou para a direita em uma
+conversa para visualizar uma mais nova ou mais antiga na mesma Caixa de entrada. Assim como ao mudar a vista dentro de uma tela, tal
+navegação não muda o comportamento de Para Cima ou Voltar.</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_gmail.png">
+
+<p>No entanto, uma exceção notável a isso ocorre ao navegar entre vistas de detalhes relacionadas não
+vinculadas pela lista de referência &mdash; por exemplo, ao navegar na Play Store entre aplicativos
+do mesmo desenvolvedor ou álbuns do mesmo artista. Nesses casos, seguir cada link cria
+um histórico, fazendo com que o botão Voltar passe por cada tela visualizada anteriormente. Para Cima deve continuar a
+ignorar essas relacionadas e navegar para a tela do contêiner visualizada mais recentemente.</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_market1.png">
+
+<p>Você tem a capacidade de deixar o comportamento de Para Cima ainda mais inteligente com base em seu conhecimento da
+vista de detalhe. Estendendo o exemplo da Play Store acima, imagine que o usuário navegou do último
+Livro visualizado para os detalhes da adaptação do Filme. Nesse caso, Para Cima pode retornar a um contêiner
+(filmes) pelo qual o usuário não navegou anteriormente.</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_market2.png">
+
+<h2 id="into-your-app">Navegação para o seu aplicativo pelos widgets de página inicial e notificações</h2>
+
+<p>Você pode usar widget de página inicial ou notificações para ajudar seus usuários a navegar diretamente para telas
+profundas na hierarquia do seu aplicativo. Por exemplo, o widget Caixa de Entrada do Gmail e a notificação de nova mensagem podem
+ignorar a tela Caixa de Entrada, levando o usuário diretamente a uma vista de conversa.</p>
+
+<p>Para esses dois casos, trate o botão Para Cima da seguinte forma:</p>
+
+<ul>
+<li><em>Se a tela de destino é normalmente acessada de uma determinada tela dentro do
+aplicativo</em>, Para Cima deve navegar para essa tela.</li>
+<li><em>Caso contrário</em>, Para Cima deve navegar para a tela superior ("Página inicial") do aplicativo.</li>
+</ul>
+
+<p>No caso do botão Voltar, você deve tornar a navegação mais previsível inserindo o caminho de navegação para cima
+completo na pilha de retorno da tarefa, até a tela superior do aplicativo. Isso permite que usuários
+que se esqueceram de como entraram no aplicativo naveguem para a tela superior do aplicativo
+antes de saírem.</p>
+
+<p>Como exemplo, o widget da Página inicial do Gmail tem um botão para mergulhar diretamente para a tela
+de composição. Para Cima ou Voltar na tela de composição deve levar o usuário à Caixa de Entrada e, de lá, o
+botão Voltar continua até a Página inicial.</p>
+
+<img src="{@docRoot}design/media/navigation_from_outside_back.png">
+
+<h4>Notificações indiretas</h4>
+
+<p>Quando o aplicativo precisa apresentar simultaneamente informações sobre vários eventos, ele pode usar
+uma única notificação que direcione o usuário a uma tela intersticial. Essa tela resume esses
+eventos e fornece caminhos para que o usuário mergulhe profundamente no aplicativo. Notificações desse estilo são
+chamadas de <em>notificações indiretas</em>.</p>
+
+<p>Diferentemente de em notificações padrão (diretas), pressionar Voltar em uma tela intersticial da
+notificação indireta retorna o usuário ao ponto em que a notificação foi acionada &mdash; nenhuma
+tela adicional é inserida na pilha de retorno. Quando o usuário prossegue para o aplicativo a partir da
+tela intersticial, Para Cima e Voltar se comportam como em notificações padrão, como descrito acima:
+navegando dentro do aplicativo em vez de voltar à tela intersticial.</p>
+
+<p>Por exemplo, suponha que um usuário no Gmail receba uma notificação indireta do Agenda. Tocar nessa
+notificação abrirá a tela intersticial, que exibirá lembretes para vários
+eventos. Tocar em Voltar na tela intersticial retornará o usuário ao Gmail. Tocar em um determinado evento
+levará o usuário da tela intersticial ao aplicativo completo do Agenda para exibir detalhes do
+evento. Dos detalhes do evento, Para Cima e Voltar navegam para a vista de nível superior do Agenda.</p>
+
+<img src="{@docRoot}design/media/navigation_indirect_notification.png">
+
+<h4>Notificações pop-up</h4>
+
+<p><em>Notificações pop-up</em> ignoram a gaveta de notificações, aparecendo diretamente na
+frente do usuário. Elas são usadas raramente e <strong>devem ser reservadas para ocasiões em que uma resposta
+rápida e a interrupção do contexto do usuário sejam necessárias</strong>. Por exemplo,
+o Talk usa esse estilo para alertar o usuário sobre um convite de um amigo para participar de uma conversa com vídeo, já que este
+convite expirará automaticamente depois de alguns segundos.</p>
+
+<p>Em termos do comportamento da navegação, notificações pop-up seguem de perto o comportamento da tela intersticial
+de uma notificação indireta. Voltar descarta a notificação pop-up. Se o usuário navegar
+da janela pop-up para o aplicativo que realizou a notificação, Para Cima e Voltar seguem as regras de notificações padrão,
+navegando dentro do aplicativo.</p>
+
+<img src="{@docRoot}design/media/navigation_popup_notification.png">
+
+<h2 id="between-apps">Navegação entre aplicativos</h2>
+
+<p>Um dos pontos fortes fundamentais do sistema Android é a capacidade dos aplicativos de ativar
+uns aos outros, dando ao usuário a capacidade de navegar diretamente de um aplicativo para outro. Por exemplo, um
+aplicativo que precisa capturar uma foto pode ativar o aplicativo Câmera, que devolverá a foto
+ao aplicativo que o chamou. Esse é um imenso benefício para o desenvolvedor, que pode aproveitar
+facilmente código de outros aplicativos, e para o usuário, que tem uma experiência consistente para ações
+comumente realizadas.</p>
+
+<p>Para entender a navegação entre aplicativos, é importante entender o comportamento da estrutura de trabalho do Android
+discutida abaixo.</p>
+
+<h4>Atividades, tarefas e intenções</h4>
+
+<p>No Android, uma <strong>atividade</strong> é um componente do aplicativo que define uma tela de
+informações e todas as ações associadas que o usuário pode executar. Seu aplicativo é uma coleção de
+atividades, consistindo em atividades que você cria e aquelas que reutiliza de outros aplicativos.</p>
+
+<p>Uma <strong>tarefa</strong> é a sequência de atividades que um usuário segue para atingir um objetivo. Uma
+única tarefa pode usar atividades apenas de um aplicativo ou pode retirar atividades de uma série
+de outros aplicativos.</p>
+
+<p>Uma <strong>intenção</strong> é um mecanismo para que um aplicativo sinalize que gostaria da assistência de outro
+aplicativo para realizar uma ação. As atividades de um aplicativo podem indicar a que intenções
+ele responde. Para intenções comuns, como "Compartilhar", o usuário pode ter vários aplicativos
+instalados que atendam a essa solicitação.</p>
+
+<h4>Exemplo: navegação entre aplicativos para suporte a compartilhamento</h4>
+
+<p>Para entender como atividades, tarefas e intenções funcionam juntas, entenda como um aplicativo permite que usuários
+compartilhem conteúdo usando outro aplicativo. Por exemplo, executar o aplicativo Play Store na tela inicial inicia
+uma nova Tarefa A (veja a figura baixo). Depois de navegar pela Play Store e tocar em um livro em promoção
+para ver os detalhes, o usuário permanecerá na mesma tarefa, estendendo-a ao adicionar atividades. Acionar
+a ação Compartilhar exibe ao usuário uma caixa de diálogo listando cada uma das atividades (de diferentes aplicativos)
+que foram registradas para tratar a intenção Compartilhar.</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_inward.png">
+
+<p>Quando o usuário seleciona o compartilhamento via Gmail, a atividade de composição do Gmail é adicionada como uma continuação da
+Tarefa A &mdash; nenhuma tarefa nova é criada. Se o Gmail tivesse a própria tarefa em execução em segundo plano, ela não
+seria afetada.</p>
+
+<p>Da atividade de composição, enviar a mensagem ou tocar no botão Voltar retornará o usuário à
+atividade de detalhes do livro. Toques subsequentes em Voltar continuarão a navegar para trás pela Play
+Store até chegar à Página inicial.</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_back.png">
+
+<p>No entanto, tocando em Para Cima na atividade de composição, o usuário indica que deseja permanecer no
+Gmail. A atividade da lista de conversas do Gmail é exibida e uma nova Tarefa B é criada para ela. Novas tarefas
+são sempre vinculadas à Página inicial, portanto, tocar em Voltar na lista de conversas retorna a ela.</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_up.png">
+
+<p>A Tarefa A persiste no segundo plano e o usuário pode voltar a ela mais tarde (por exemplo, via tela
+Recentes). Se o Gmail já tivesse a própria tarefa em execução em segundo plano, ela seria substituída
+pela Tarefa B &mdash; o contexto anterior é abandonado em favor do novo objetivo do usuário.</p>
+
+<p>Quando o aplicativo é registrado para tratar intenções com uma atividade em um ponto profundo da hierarquia do aplicativo,
+consulte <a href="#into-your-app">Navegação para o seu aplicativo pelos widgets de página
+inicial e notificações</a> para ver orientações sobre como especificar a navegação Para Cima.</p>
diff --git a/docs/html-intl/intl/pt-br/design/patterns/notifications.jd b/docs/html-intl/intl/pt-br/design/patterns/notifications.jd
new file mode 100644
index 0000000..efea610
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/design/patterns/notifications.jd
@@ -0,0 +1,872 @@
+page.title=Notificações
+page.tags="notifications","design","L"
+@jd:body
+
+ <a class="notice-developers" href="{@docRoot}training/notify-user/index.html">
+ <div>
+ <h3>Documentos do desenvolvedor</h3>
+ <p>Notificação ao usuário</p>
+ </div>
+</a>
+
+<a class="notice-designers" href="notifications_k.html">
+ <div>
+ <h3>Notificações no Android 4.4 e em anteriores</h3>
+ </div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=Uiq2kZ2JHVY">
+<div>
+ <h3>Vídeo</h3>
+ <p>DevBytes: Notificações na pré-visualização do desenvolvedor do Android L</p>
+</div>
+</a>
+
+<style>
+ .col-5, .col-6, .col-7 {
+ margin-left:0px;
+ }
+</style>
+
+<p>O sistema de notificações permite que os usuários se mantenham informados sobre eventos relevantes e
+imediatos
+no aplicativo, como novas mensagens de bate-papo de um amigo ou um evento de calendário.
+Pense nas notificações como um canal de notícias que alerta o usuário sobre eventos
+importantes à
+medida que acontecem ou sobre um registro que grava eventos enquanto o usuário não está prestando
+atenção &mdash; e que é sincronizado conforme apropriado em todos os dispositivos Android dele.</p>
+
+<h4 id="New"><strong>Novo no Android 5.0</strong></h4>
+
+<p>No Android 5.0, as notificações recebem atualizações importantes: em termos estruturais, visuais e
+funcionais:</p>
+
+<ul>
+ <li>As notificações passaram por mudanças visuais consistentes com o novo
+tema do Material Design.</li>
+ <li> As notificações agora estão disponíveis na tela de bloqueio do dispositivo, enquanto que
+o conteúdo sensível ainda pode
+ficar oculto atrás dela.</li>
+ <li>Notificações de alta prioridade recebidas enquanto o dispositivo está em uso agora usam um novo formato, chamado de
+notificações heads-up.</li>
+ <li>Notificações sincronizadas na nuvem: descartar uma notificação em um dos
+dispositivos Android a descarta
+também nos outros.</li>
+</ul>
+
+<p class="note"><strong>Observação:</strong> o projeto de notificação nesta versão do
+Android é uma mudança
+significativa em relação às versões anteriores. Para obter informações sobre o projeto de notificação em versões
+anteriores, consulte <a href="./notifications_k.html">Notificações no Android 4.4 ou em anteriores</a>.</p>
+
+<h2 id="Anatomy">Anatomia de uma notificação</h2>
+
+<p>Esta seção aborda as partes básicas de uma notificação e como elas
+podem aparecer em diferentes tipos de dispositivos.</p>
+
+<h3 id="BaseLayout">Layout básico</h3>
+
+<p>No mínimo, todas as notificações consistem em um layout básico, incluindo:</p>
+
+<ul>
+ <li> O <strong>ícone</strong> da notificação. O ícone simboliza o
+aplicativo de origem. Ele também
+ pode indicar o tipo de notificação, caso o aplicativo gere mais de um
+tipo.</li>
+ <li> Um <strong>título</strong> da notificação e
+<strong>texto</strong> adicional.</li>
+ <li> Uma <strong>marcação de data e hora</strong>.</li>
+</ul>
+
+<p>Notificações criadas com {@link android.app.Notification.Builder Notification.Builder}
+para versões anteriores da plataforma têm a mesma aparência e o mesmo funcionamento no Android
+5.0, com apenas mudanças menores de estilo que o sistema
+entrega a você. Para obter mais informações sobre notificações em versões
+anteriores do Android, consulte
+<a href="./notifications_k.html">Notificações no Android 4.4 ou em anteriores</a>.</p></p>
+
+
+ <img style="margin:20px 0 0 0" src="{@docRoot}images/android-5.0/notifications/basic_combo.png" alt="" width="700px" />
+
+
+<div style="clear:both;margin-top:20px">
+ <p class="img-caption">
+ Layout básico de uma notificação em dispositivo portátil (à esquerda) e a mesma notificação em Wear (à direita),
+com uma foto do usuário e um ícone de notificação
+ </p>
+ </div>
+
+<h3 id="ExpandedLayouts">Layouts expandidos</h3>
+
+
+<p>Você pode escolher o nível de detalhe que as notificações de seu aplicativo
+devem fornecer. Elas podem mostrar as primeiras
+linhas de uma mensagem ou exibir uma visualização de imagem maior. As informações
+adicionais fornecem ao usuário mais
+contexto e &mdash; em alguns casos &mdash; podem permitir que o usuário leia uma mensagem
+em sua totalidade. O usuário pode
+pinçar para aproximar ou afastar a vista ou realizar deslizamento de um dedo para alternar entre os layouts
+compacto e expandido.
+ Para notificações de um evento, o Android fornece três modelos de layout
+expandido (texto, caixa de entrada e
+ imagem) para usar em seu aplicativo. As imagens a seguir mostram como
+se parecem notificações de um evento em
+ dispositivos portáteis (à esquerda) e usados junto ao corpo (à direita).</p>
+
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/expandedtext_combo.png"
+ alt="" width="700px" height;="284px" />
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/stack_combo.png"
+ alt="" width="700px" height;="284px" />
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/ExpandedImage.png"
+ alt="" width="311px" height;="450px" />
+
+<h3 id="actions" style="clear:both; margin-top:40px">Ações</h3>
+
+<p>O Android tem suporte para ações opcionais que são exibidas na parte inferior
+da notificação.
+Com ações, os usuários podem tratar as tarefas mais comuns para
+determinada notificação de dentro da sombra da notificação sem precisar abrir o
+aplicativo de origem.
+Isso acelera a interação e, em conjunto com deslizar-para-descartar, ajuda os usuários a
+se concentrarem em notificações que sejam importantes.</p>
+
+
+ <img src="{@docRoot}images/android-5.0/notifications/action_combo.png" alt="" width="700px" />
+
+
+
+<p style="clear:both">Tenha cuidado com o número de ações que inclui em uma
+notificação. Quanto mais
+ações incluir, maior será a complexidade cognitiva criada. Limite-se
+ao menor número possível
+de ações, incluindo apenas as ações efetivamente mais importantes e
+significativas.</p>
+
+<p>Boas candidatas a ações em notificações são ações que:</p>
+
+<ul>
+ <li> Sejam essenciais, frequentes e típicas para o tipo de conteúdo
+exibido
+ <li> Permitam que o usuário realize tarefas rapidamente
+</ul>
+
+<p>Evite ações que sejam:</p>
+
+<ul>
+ <li> Ambíguas
+ <li> Idênticas à ação padrão da notificação (como "Ler" ou
+"Abrir")
+</ul>
+
+
+
+<p>Você pode especificar no máximo três ações, cada uma consistindo em um ícone
+e um nome de ação.
+ Adicionar ações a um layout básico simples torna a notificação expansível,
+mesmo se a
+notificação não tiver um layout expandido. Como as ações são exibidas apenas para notificações
+expandidas
+ e que ficam de outra forma ocultas, certifique-se de que qualquer ação que um
+usuário possa invocar de dentro de uma
+ notificação esteja disponível também dentro do aplicativo
+associado.</p>
+
+<h2 style="clear:left">Notificação heads-up</h2>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/hun-example.png" alt="" width="311px" />
+ <p class="img-caption">
+ Exemplo de uma notificação heads-up (chamada telefônica recebida, alta prioridade)
+que aparece sobre um
+aplicativo imersivo
+ </p>
+</div>
+
+<p>Quando uma notificação de alta prioridade chega (veja à direita), ela é apresentada
+aos usuários por
+um período curto com um layout expandido mostrando possíveis ações.</p>
+<p> Depois desse período, a notificação recua para a sombra
+de notificação. Se a <a href="#correctly_set_and_manage_notification_priority">prioridade</a> de uma notificação for
+marcada como Alta, Máxima ou tela cheia, ela receberá uma notificação heads-up.</p>
+
+<p><b>Bons exemplos de notificações heads-up</b></p>
+
+<ul>
+ <li> Chamada telefônica recebida durante o uso do dispositivo</li>
+ <li> Alarme durante o uso do dispositivo</li>
+ <li> Nova mensagem SMS</li>
+ <li> Bateria fraca</li>
+</ul>
+
+<h2 style="clear:both" id="guidelines">Diretrizes</h2>
+
+
+<h3 id="MakeItPersonal">Torne-a pessoal</h3>
+
+<p>Para notificações de itens enviados por outra pessoa (como uma mensagem ou
+atualização de status), inclua a imagem da pessoa usando
+{@link android.app.Notification.Builder#setLargeIcon setLargeIcon()}. Anexe também informações sobre
+a pessoa nos metadados da notificação (consulte {@link android.app.Notification#EXTRA_PEOPLE}).</p>
+
+<p>O ícone principal de sua notificação ainda é mostrado, portanto, o usuário pode associá-lo
+ao ícone
+visível na barra de status.</p>
+
+
+<img src="{@docRoot}images/android-5.0/notifications/Triggered.png" alt="" width="311px" />
+<p style="margin-top:10px" class="img-caption">
+ Notificação que mostra a pessoa que a ativou e o conteúdo enviado.
+</p>
+
+
+<h3 id="navigate_to_the_right_place">Navegação para o lugar certo</h3>
+
+<p>Quando o usuário toca no corpo de uma notificação (fora dos botões
+de ação), abra o aplicativo
+no lugar em que o usuário possa visualizar e agir sobre os dados referenciados na
+notificação. Na maioria dos casos, será a exibição detalhada de um único item de dado, como uma mensagem,
+mas também poderá ser uma
+vista resumida se a notificação estiver empilhada. Se o aplicativo
+levar o usuário a qualquer lugar abaixo do nível superior do aplicativo, insira a navegação na pilha de retorno do aplicativo para que
+o usuário possa pressionar o botão Voltar do sistema para voltar ao nível superior. Para obter mais informações, consulte
+<em>Navegação para o seu aplicativo pelos widgets de página inicial e notificações</em> no padrão de projeto de <a href="{@docRoot}design/patterns/navigation.html#into-your-app">Navegação</a>.
+</p>
+
+<h3 id="correctly_set_and_manage_notification_priority">Definição e gerenciamento
+corretos da prioridade das
+notificações</h3>
+
+<p>O Android tem suporte para um sinalizador de prioridade para notificações. Esse sinalizador permite
+influenciar o local em que a notificação é exibida em relação a outras notificações e
+ajuda a garantir
+que os usuários sempre vejam primeiro as notificações mais importantes. Você pode escolher entre
+os seguintes
+níveis de prioridade ao publicar uma notificação:</p>
+<table>
+ <tr>
+ <td class="tab0">
+<p><strong>Prioridade</strong></p>
+</td>
+ <td class="tab0">
+<p><strong>Uso</strong></p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>MAX</code></p>
+</td>
+ <td class="tab1">
+<p>Use para notificações críticas e urgentes que alertam o usuário sobre uma condição
+que depende
+do tempo ou que precisa ser resolvida antes que o usuário possa continuar
+com uma determinada tarefa.</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>HIGH</code></p>
+</td>
+ <td class="tab1">
+<p>Use principalmente para comunicações importantes, como uma mensagem ou
+eventos de bate-papo com conteúdo particularmente interessante para o usuário.
+Notificações de alta prioridade acionam a exibição de uma notificação heads-up.</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>DEFAULT</code></p>
+</td>
+ <td class="tab1">
+<p>Use para todas as notificações que não recaiam em nenhuma das outras prioridades descritas aqui.</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>LOW</code></p>
+</td>
+ <td class="tab1">
+<p>Use para notificações sobre as quais deseja que o usuário seja informado, mas
+que sejam menos urgentes. Notificações de baixa prioridade tendem a ser exibidas na parte inferior da lista,
+o que as torna uma boa
+opção para coisas como atualizações públicas ou sociais não direcionadas: o usuário pediu para
+ser notificado sobre
+elas, mas essas notificações nunca devem ter precedência sobre comunicações
+urgentes ou diretas.</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>MIN</code></p>
+</td>
+ <td class="tab1">
+<p>Use para informações contextuais ou de histórico, como informações sobre clima ou
+informações contextuais de localização.
+Notificações de prioridade mínima não aparecem na barra de status. O usuário
+as descobre expandindo a sombra da notificação.</p>
+</td>
+ </tr>
+</table>
+
+
+<h4 id="how_to_choose_an_appropriate_priority"><strong>Como escolher uma prioridade
+adequada
+</strong></h4>
+
+<p><code>DEFAULT</code>, <code>HIGH</code> e <code>MAX</code> são níveis de prioridade de interrupção e arriscam
+interromper a atividade
+do usuário. Para evitar irritar os usuários de seu aplicativo, reserve níveis de prioridade de interrupção para
+notificações que:</p>
+
+<ul>
+ <li> Envolvam outra pessoa</li>
+ <li> Dependam do tempo</li>
+ <li> Possam mudar imediatamente o comportamento do usuário no mundo real</li>
+</ul>
+
+<p>Notificações definidas como <code>LOW</code> e <code>MIN</code> ainda podem
+ser valiosas para o usuário: muitas, se não a maioria, das notificações não precisam demandar a atenção
+imediata do usuário, ou vibrar o pulso do usuário, mas ainda contêm informações que o usuário
+achará valiosas ao decidir procurar
+notificações. Os critérios para notificações de prioridade <code>LOW</code> e <code>MIN</code>
+incluem:</p>
+
+<ul>
+ <li> Não envolver outras pessoas</li>
+ <li> Não depender de tempo</li>
+ <li> Ter conteúdo no qual o usuário pode estar interessado, mas que pode decidir
+verificar no momento em que desejar</li>
+</ul>
+
+
+ <img src="{@docRoot}images/android-5.0/notifications/notifications_pattern_priority.png" alt="" width="700" />
+
+
+<h3 style="clear:both" id="set_a_notification_category">Definição de uma categoria
+de notificação</h3>
+
+<p>Se a sua notificação recair em uma das categorias predefinidas (veja
+abaixo), atribua-a
+adequadamente. Aspectos da IU do sistema, como a sombra da notificação (ou qualquer
+outra escuta
+de notificação), podem usar essas informações para tomar decisões de classificação e filtragem.</p>
+<table>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_CALL">CATEGORY_CALL</a></code></p>
+</td>
+ <td>
+<p>Chamada recebida (voz ou vídeo) ou solicitação similar de
+comunicação síncrona</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_MESSAGE">CATEGORY_MESSAGE</a></code></p>
+</td>
+ <td>
+<p>Mensagem direta recebida (SMS, mensagem instantânea etc.)</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_EMAIL">CATEGORY_EMAIL</a></code></p>
+</td>
+ <td>
+<p>Mensagens assíncronas em lote (e-mail)</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_EVENT">CATEGORY_EVENT</a></code></p>
+</td>
+ <td>
+<p>Evento de calendário</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_PROMO">CATEGORY_PROMO</a></code></p>
+</td>
+ <td>
+<p>Promoção ou publicidade</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_ALARM">CATEGORY_ALARM</a></code></p>
+</td>
+ <td>
+<p>Alarme ou cronômetro</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_PROGRESS">CATEGORY_PROGRESS</a></code></p>
+</td>
+ <td>
+<p>Andamento de uma operação de execução longa em segundo plano</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SOCIAL">CATEGORY_SOCIAL</a></code></p>
+</td>
+ <td>
+<p>Atualização de rede social ou de compartilhamento</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_ERROR">CATEGORY_ERROR</a></code></p>
+</td>
+ <td>
+<p>Erro em operação de segundo plano ou no status de autenticação</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_TRANSPORT">CATEGORY_TRANSPORT</a></code></p>
+</td>
+ <td>
+<p>Controle de transporte de mídia para reprodução</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SYSTEM">CATEGORY_SYSTEM</a></code></p>
+</td>
+ <td>
+<p>Atualização do sistema ou do status do dispositivo. Reservado para uso do sistema.</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SERVICE">CATEGORY_SERVICE</a></code></p>
+</td>
+ <td>
+<p>Indicação de serviço de segundo plano em execução</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_RECOMMENDATION">CATEGORY_RECOMMENDATION</a></code></p>
+</td>
+ <td>
+<p>Uma recomendação específica e oportuna para uma única coisa. Por exemplo, um aplicativo
+de notícias pode querer
+recomendar uma notícia que acredita que o usuário desejará ler em seguida.</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_STATUS">CATEGORY_STATUS</a></code></p>
+</td>
+ <td>
+<p>Informações contínuas sobre o dispositivo ou o status contextual</p>
+</td>
+ </tr>
+</table>
+
+<h3 id="summarize_your_notifications">Resuma as notificações</h3>
+
+<p>Se uma notificação de um certo tipo já estiver pendente quando o aplicativo tentar enviar uma nova
+notificação do mesmo tipo, combine-as em uma única notificação de resumo para o aplicativo. Não
+crie um novo objeto.</p>
+
+<p>Uma notificação de resumo cria uma descrição resumida e permite que o
+usuário entenda quantas notificações
+de um determinado tipo estão pendentes.</p>
+
+<div class="col-6">
+
+<p><strong>O que não fazer</strong></p>
+ <img src="{@docRoot}images/android-5.0/notifications/Summarise_Dont.png" alt="" width="311px" />
+</div>
+
+<div>
+<p><strong>O que fazer</strong></p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/Summarise_Do.png" alt="" width="311px" />
+</div>
+
+<p style="clear:left; padding-top:30px; padding-bottom:20px">Você pode fornecer
+mais detalhes sobre as notificações individuais que compõem um
+resumo usando o layout resumido expandido. Essa abordagem permite que os usuários
+entendam melhor quais
+notificações estão pendentes e decidam se estão interessados o suficiente para lê-las
+em detalhes dentro
+do aplicativo associado.</p>
+<div class="col-6">
+ <img src="{@docRoot}images/android-5.0/notifications/Stack.png" style="margin-bottom:20px" alt="" width="311px" />
+ <p class="img-caption">
+ Notificação expandida e contraída que é um resumo (usando <code>InboxStyle</code>)
+ </p>
+</div>
+
+<h3 style="clear:both" id="make_notifications_optional">Torne as notificações
+opcionais</h3>
+
+<p>Os usuários devem sempre controlar as notificações. Permita que o usuário
+desative as notificações
+de seu aplicativo ou altere as propriedades de alerta, como som de alerta e
+se a vibração será usada,
+adicionando um item de configuração da notificação nas configurações do aplicativo.</p>
+
+<h3 id="use_distinct_icons">Use ícones distintos</h3>
+<p>Ao olhar para a área de notificação, o usuário deverá ser capaz de discernir
+que tipos de
+notificações estão atualmente pendentes.</p>
+
+<div class="figure">
+ <img src="{@docRoot}images/android-5.0/notifications/ProductIcons.png" alt="" width="420" />
+</div>
+
+ <div><p><strong>O que fazer</strong></p>
+ <p>Verifique os ícones de notificação que os aplicativos do Android já fornecem e crie
+ícones de notificação para o seu
+aplicativo que tenham aparência suficientemente distinta.</p>
+
+ <p><strong>O que fazer</strong></p>
+ <p>Use o <a href="/design/style/iconography.html#notification">estilo de ícone de notificação</a> apropriado
+ para ícones pequenos e o
+ <a href="/design/style/iconography.html#action-bar">estilo de ícone de barra
+de ação</a> da luminosidade do Material para os ícones
+ de ação.</p>
+<p ><strong>O que fazer</strong></p>
+<p >Mantenha os ícones visualmente simples, evitando detalhes excessivos que sejam
+difíceis de discernir.</p>
+
+ <div><p><strong>O que não fazer</strong></p>
+ <p>Coloque um alfa adicional (esmaecimento ou redução de intensidade) nos ícones pequenos
+e nos ícones de
+ ação; eles podem ter bordas suavizadas, mas, como o Android usa esses
+ícones como máscaras (ou seja, somente
+ o canal alfa é usado), a imagem normalmente deve ser desenhada com
+opacidade total.</p>
+
+</div>
+<p style="clear:both"><strong>O que não fazer</strong></p>
+
+<p>Use cores para distinguir o seu aplicativo dos outros. Ícones de notificação devem
+somente ser uma imagem com fundo branco sobre transparente.</p>
+
+
+<h3 id="pulse_the_notification_led_appropriately">Pisque o LED de notificação
+adequadamente</h3>
+
+<p>Muitos dispositivos Android contêm um LED de notificação, que é usado para manter o
+usuário informado sobre
+eventos enquanto a tela está desligada. Notificações com um nível de prioridade de <code>MAX</code>,
+<code>HIGH</code> ou <code>DEFAULT</code> devem
+fazer com que o LED brilhe, enquanto que os de prioridade mais baixa (<code>LOW</code> e
+<code>MIN</code>) não devem.</p>
+
+<p>O controle do usuário sobre as notificações deve se estender ao LED. Ao usar
+DEFAULT_LIGHTS, o
+LED brilhará na cor branca. Suas notificações não devem usar uma cor
+diferente, a não ser que o
+usuário as tenha explicitamente personalizado.</p>
+
+<h2 id="building_notifications_that_users_care_about">Criação de notificações
+que agradam aos usuários</h2>
+
+<p>Para criar um aplicativo que os usuários amem, é importante projetar as
+notificações cuidadosamente.
+As notificações personificam a voz do seu aplicativo e contribuem para
+a personalidade dele. Notificações indesejadas ou
+irrelevantes podem irritar o usuário ou fazer com que ele reprove a
+quantidade de atenção que o
+aplicativo exige. Portanto, use notificações de forma cuidadosa.</p>
+
+<h3 id="when_to_display_a_notification">Quando exibir uma notificação</h3>
+
+<p>Para criar um aplicativo que as pessoas gostem de usar, é importante
+reconhecer que a atenção e o foco
+do usuário são recursos que devem ser protegidos. Apesar de o sistema de
+notificação do Android ter
+sido projetado para minimizar o impacto das notificações na atenção do usuário,
+ainda é
+importante ter ciência do fato de que as notificações interrompem o
+fluxo de tarefas do usuário.
+Ao planejar as notificações, pergunte-se se elas são importantes o suficiente para
+justificar uma interrupção. Se não tiver certeza, permita que o usuário decida se quer
+uma notificação usando as configurações de notificação do seu aplicativo ou ajuste
+o sinalizador de prioridade das notificações para <code>LOW</code> ou <code>MIN</code> para
+evitar distrair o usuário enquanto ele faz
+alguma outra coisa.</p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/TimeSensitive.png" alt="" width="311px" />
+ <p style="margin-top:10px" class="img-caption">
+ Exemplos de notificação que depende de tempo
+ </p>
+
+<p>Apesar de aplicativos bem comportados geralmente se manifestarem apenas quando ocorre interação com eles, alguns
+casos justificam que o aplicativo interrompa o usuário com uma notificação não solicitada.</p>
+
+<p>Use notificações principalmente para <strong>eventos que dependam de tempo</strong>, especialmente
+ se esses eventos síncronos <strong>envolverem outras pessoas</strong>. Por
+exemplo, um bate-papo recebido
+é uma forma síncrona em tempo real de comunicação: outro usuário
+espera ativamente a resposta. Eventos de calendário são outro exemplo bom de quando usar uma
+notificação e atrair a
+atenção do usuário, pois o evento é iminente e eventos de calendário frequentemente
+envolvem outras pessoas.</p>
+
+<h3 style="clear:both" id="when_not_to_display_a_notification">Quando não exibir
+uma notificação</h3>
+
+<div class="figure" style="margin-top:60px">
+ <img src="{@docRoot}images/android-5.0/notifications/AntiSample1.png" alt="" width="311px" />
+</div>
+
+<p>Em muitos outros casos, notificações não são adequadas:</p>
+
+<ul>
+ <li> Evite notificar o usuário sobre informações que não são especificamente
+direcionadas a ele ou
+que não dependam realmente de tempo. Por exemplo, as atualizações
+assíncronas e não direcionadas
+que fluem por uma rede social geralmente não justificam uma interrupção
+em tempo real. Para os usuários que se importam
+com elas, deixe que decidam recebê-las.</li>
+ <li> Não crie uma notificação se as informações novas relevantes estiverem
+atualmente na tela. Em vez disso,
+use a IU do próprio aplicativo para notificar o usuário das novas informações
+diretamente no contexto.
+ Por exemplo, um aplicativo de bate-papo não deve criar notificações de sistema enquanto o
+usuário estiver conversando ativamente com outro usuário.</li>
+ <li> Não interrompa o usuário para realizar operações técnicas de baixo nível, como salvar
+ou sincronizar informações, nem atualize um aplicativo se o aplicativo ou o sistema puder resolver
+o problema sem envolver o usuário.</li>
+ <li> Não interrompa o usuário para informar um erro se o aplicativo
+puder se recuperar dele por conta própria, sem que o usuário
+tome qualquer ação.</li>
+ <li> Não crie notificações que não tenham conteúdo real de notificação e
+que meramente anunciem o seu
+aplicativo. Uma notificação deve fornecer informações úteis, oportunas e novas e
+não deve ser usada
+meramente para executar um aplicativo.</li>
+ <li> Não crie notificações supérfluas apenas para colocar sua marca na frente
+dos usuários.
+ Tais notificações frustram e provavelmente alienam seu público-alvo. A
+melhor forma de fornecer
+ pequenas quantidades de informações atualizadas e manter o usuário envolvido
+com o seu
+ aplicativo é desenvolver um widget que ele possa colocar na
+tela inicial.</li>
+</ul>
+
+<h2 style="clear:left" id="interacting_with_notifications">Interação com
+notificações</h2>
+
+<p>Notificações são indicadas por ícones na barra de status e podem ser acessadas
+abrindo a
+gaveta de notificações.</p>
+
+<p>Tocar em uma notificação abre o aplicativo associado com o conteúdo
+detalhado que corresponde à notificação.
+Deslizar à esquerda ou à direita em uma notificação a remove da gaveta.</p>
+
+<h3 id="ongoing_notifications">Notificações contínuas</h3>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/MusicPlayback.png" alt="" width="311px" />
+ <p class="img-caption">
+ Notificação contínua devido à reprodução de música
+ </p>
+</div>
+<p>Notificações contínuas mantêm os usuários informados sobre um processo em andamento em
+segundo plano.
+Por exemplo, reprodutores de música anunciam a faixa em reprodução no
+sistema de notificação e
+continuam a fazer isso até que o usuário interrompa a reprodução. Notificações contínuas também podem
+mostrar ao usuário
+feedback sobre tarefas mais longas, como o download de um arquivo ou a codificação de um vídeo. Um usuário não pode remover
+manualmente uma notificação contínua da gaveta de notificações.</p>
+
+<h3 id="ongoing_notifications">Reprodução de mídia</h3>
+<p>No Android 5.0, a tela de bloqueio não mostra controles de transporte por causa da classe
+{@link android.media.RemoteControlClient} obsoleta. Mas ela <em>mostra</em> notificações, portanto, a notificação de reprodução
+de cada aplicativo agora é a forma
+principal para que os usuários controlem a reprodução em um estado bloqueado. Esse comportamento dá aos aplicativos mais
+controle sobre quais
+botões exibir e de que forma, ao mesmo tempo em que fornece uma experiência consistente
+para o usuário, com a tela bloqueada ou não.</p>
+
+<h3 style="clear:both"
+id="dialogs_and_toasts_are_for_feedback_not_notification">Diálogos
+e avisos</h3>
+
+<p>O seu aplicativo não deve criar uma caixa de diálogo ou um aviso se não estiver
+atualmente na tela. Uma caixa de diálogo ou um aviso
+ deve ser exibido somente como uma resposta imediata ao usuário tomando uma ação
+dentro do seu aplicativo.
+Para obter orientação adicional sobre o uso de caixas de diálogo e avisos, consulte
+<a href="/design/patterns/confirming-acknowledging.html">Confirmação e reconhecimento</a>.</p>
+
+<h3>Avaliação e classificação</h3>
+
+<p>Notificações são notícias e, portanto, são essencialmente exibidas
+em ordem cronológica inversa, com
+consideração especial para a
+<a href="#correctly_set_and_manage_notification_priority">prioridade</a> da notificação declarada no aplicativo.</p>
+
+<p>Notificações são uma parte importante da tela de bloqueio e são exibidas proeminentemente
+sempre
+que a tela do dispositivo é exibida. O espaço na tela de bloqueio é restrito, portanto,
+é mais importante
+do que nunca identificar as notificações mais urgentes ou relevantes. Por esse
+motivo, o Android tem um
+algoritmo de classificação mais sofisticado para notificações, levando em conta:</p>
+
+<ul>
+ <li> A marcação de data e hora e a prioridade declarada no aplicativo.</li>
+ <li> Se a notificação incomodou recentemente o usuário com som ou
+vibração (ou seja,
+ se o celular acabou de fazer um ruído e o usuário deseja saber "O que acabou de
+acontecer?", a tela de bloqueio
+ deve responder com um olhar rápido).</li>
+ <li> Qualquer pessoa anexada à notificação usando {@link android.app.Notification#EXTRA_PEOPLE}
+ e, em particular, se é contato especial (com estrelas).</li>
+</ul>
+
+<p>Para aproveitar ao máximo essa classificação, concentre-se na experiência
+do usuário que deseja
+criar, e não em um determinado local na lista.</p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/AntiSample3.png" alt="" width="700px" />
+
+ <p class="img-caption" style="margin-top:10px">Notificações do Gmail têm
+prioridade padrão e normalmente
+ são classificadas abaixo de mensagens de um aplicativo de mensagem instantânea, como o Hangouts, mas
+recebem
+ uma promoção temporária quando novas mensagens chegam.
+ </p>
+
+
+<h3>Na tela de bloqueio</h3>
+
+<p>Como as notificações são visíveis na tela de bloqueio, a privacidade do usuário é uma consideração
+especialmente
+ importante. Notificações frequentemente contêm informações sensíveis e
+não devem necessariamente estar visíveis
+para qualquer pessoa que ligar a tela do dispositivo.</p>
+
+<ul>
+ <li> Para dispositivos que têm uma tela de bloqueio segura (PIN, padrão ou senha), a interface tem
+partes públicas e privadas. A interface pública pode ser exibida em uma tela de bloqueio segura e,
+portanto, vista por qualquer pessoa. A interface privada é o mundo atrás da tela de bloqueio e
+só é revelada depois que o usuário faz login no dispositivo.</li>
+</ul>
+
+<h3>Controle do usuário sobre as informações exibidas na tela de bloqueio segura</h3>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/LockScreen@2x.png" srcset="{@docRoot}images/android-5.0/notifications/LockScreen.png 1x" alt="" width="311px" />
+ <p class="img-caption">
+ Notificações na tela de bloqueio com conteúdo revelado depois que o usuário desbloqueia o dispositivo.
+ </p>
+</div>
+
+<p>Ao definir uma tela de bloqueio segura, o usuário poderá escolher ocultar
+detalhes sensíveis da tela de bloqueio segura. Nesse caso, a IU do sistema
+considerará o <em>nível de visibilidade</em> da notificação para descobrir o que pode
+ser exibido com segurança.</p>
+<p> Para controlar o nível de visibilidade, chame
+<code><a
+href="/reference/android/app/Notification.Builder.html#setVisibility(int)">Notification.Builder.setVisibility()</a></code>
+e especifique um destes valores:</p>
+
+<ul>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_PUBLIC">VISIBILITY_PUBLIC</a></code>.
+Exibe o conteúdo inteiro da notificação.
+ Esse é o padrão do sistema se a visibilidade não for especificada.</li>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_PRIVATE">VISIBILITY_PRIVATE</a></code>.
+Na tela de bloqueio, exibe informações básicas sobre essa notificação, incluindo o
+ícone e o nome do aplicativo que a publicou. O restante dos detalhes da notificação não é exibido.
+Alguns pontos a ter em mente são:
+ <ul>
+ <li> Se você quer fornecer uma versão pública diferente da sua notificação
+para que o sistema a exiba em uma tela de bloqueio segura, forneça um objeto
+Notificação substituto no campo <code><a
+href="/reference/android/app/Notification.html#publicVersion">Notification.publicVersion</a></code>.
+
+ <li> Essa configuração dá ao aplicativo uma oportunidade de criar uma versão alternativa do
+conteúdo que ainda é útil, mas não revela informações pessoais. Considere o exemplo de um
+aplicativo de SMS cujas notificações incluem o texto da mensagem SMS, o nome do remetente e o ícone do contato.
+Essa notificação deve ser <code>VISIBILITY_PRIVATE</code>, mas <code>publicVersion</code> ainda pode
+conter informações úteis, como "3 novas mensagens", sem outros detalhes
+de identificação.
+ </ul>
+ </li>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_SECRET">Notification.VISIBILITY_SECRET</a></code>. Mostra apenas as informações mínimas, excluindo até mesmo
+o ícone da notificação.</li>
+</ul>
+<h2 style="clear:both" id="notifications_on_android_wear">Notificações no
+Android Wear</h2>
+
+<p>Notificações e suas <em>ações</em> são enviadas a dispositivos Wear por padrão.
+Os desenvolvedores podem controlar que notificações são enviadas do
+celular ao relógio
+e vice-versa. Os desenvolvedores também podem controlar quais ações são transmitidas. Se o
+seu aplicativo inclui
+ações que não podem ser executadas com um toque, oculte essas ações
+na sua notificação do Wear
+ou considere colocá-las em um aplicativo do Wear, permitindo que o usuário
+termine a ação
+no relógio.</p>
+
+<h4>Transmissão de notificações e ações</h4>
+
+<p>Um dispositivo conectado, como um celular, pode transmitir notificações para um dispositivo Wear para que as
+notificações sejam exibidas nele. De forma similar, ele pode transmitir ações para que o usuário possa agir
+sobre as notificações diretamente do dispositivo Wear.</p>
+
+<p><strong>Transmitir</strong></p>
+
+<ul>
+ <li> Novas mensagens instantâneas</li>
+ <li> Ações de um toque, como +1, Curtir, Coração</li>
+</ul>
+
+<img src="{@docRoot}images/android-5.0/notifications/WearBasic.png" width="156px" height="156px" alt="" />
+
+<p><strong>Não transmitir</strong></p>
+
+<ul>
+ <li> Notificações de podcasts recém-chegados</li>
+ <li> Ações que mapeiem para recursos que não são possíveis no relógio</li>
+</ul>
+
+
+
+<p><h4>Ações exclusivas a definir para Wear</h4></p>
+
+<p>Há algumas ações que só podem ser realizadas em Wear. Elas incluem:</p>
+
+<ul>
+ <li> Listas rápidas de respostas prontas, como "Volto logo"</li>
+ <li> Abrir no celular</li>
+ <li> Uma ação "Comentar" ou "Responder" que abre a tela de entrada de voz</li>
+ <li> Ações que executam aplicativos específicos de Wear</li>
+</ul>
+
+<img src="{@docRoot}images/android-5.0/notifications/ReplyAction.png" width="156px" height="156px" alt="" />
diff --git a/docs/html-intl/intl/pt-br/preview/api-overview.jd b/docs/html-intl/intl/pt-br/preview/api-overview.jd
new file mode 100644
index 0000000..33e8c1f
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/api-overview.jd
@@ -0,0 +1,521 @@
+page.title=Visão geral da API
+page.keywords=preview,sdk,compatibility
+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>Neste documento
+ <a href="#" onclick="hideNestedItems('#toc44',this);return false;" class="header-toggle">
+ <span class="more">mostrar mais</span>
+ <span class="less" style="display:none">mostrar menos</span></a></h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#app-linking">Vínculo de aplicativo</a></li>
+ <li><a href="#backup">Backup automático para aplicativos</a></li>
+ <li><a href="#authentication">Autenticação</a>
+ <ol>
+ <li><a href="#fingerprint-authentication">Autenticação com impressão digital</a></li>
+ <li><a href="#confirm-credential">Confirmação de credencial</a></li>
+ </ol>
+ </li>
+ <li><a href="#direct-share">Compartilhamento direto</a></li>
+ <li><a href="#voice-interactions">Interações por voz</a></li>
+ <li><a href="#assist">Auxiliar API</a></li>
+ <li><a href="#notifications">Notificações</a></li>
+ <li><a href="#bluetooth-stylus">Suporte para Bluetooth Stylus</a></li>
+ <li><a href="#ble-scanning">Digitalização de baixa energia por Bluetooth aprimorada</a></li>
+ <li><a href="#hotspot">Suporte a Hotspot 2.0 Release 1</a></li>
+ <li><a href="#4K-display">Modo de exibição 4K</a></li>
+ <li><a href="#behavior-themeable-colorstatelists">ColorStateLists com tema</a></li>
+ <li><a href="#audio">Recursos de áudio</a></li>
+ <li><a href="#video">Recursos de vídeo</a></li>
+ <li><a href="#camera">Recursos de câmera</a>
+ <ol>
+ <li><a href="#flashlight">API da lanterna</a></li>
+ <li><a href="#reprocessing">Reprocessamento da câmera</a></li>
+ </ol>
+ </li>
+ <li><a href="#afw">Recursos do Android for Work</a></li>
+</ol>
+
+<h2>Diferenças de API</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">API de nível 22 para M Preview &raquo;</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>O M Developer Preview fornece uma visualização avançada no próximo lançamento
+ para a plataforma Android, oferecendo novos recursos para desenvolvedores e usuários
+de aplicativos. Este documento fornece uma introdução às APIs mais notáveis.</p>
+
+<p>O M Developer Preview foi feito para <strong>novos desenvolvedores
+adotantes</strong> e <strong>testadores</strong>. Caso tenha interesse
+ em influenciar a direção da estrutura do Android,
+<a href="{@docRoot}preview/setup-sdk.html">experimente o M Developer
+ Preview</a> e envie-nos feedback!</p>
+
+<p class="caution"><strong>Cuidado:</strong> não publique aplicativos
+que usam o M Developer Preview na Google Play Store.</p>
+
+<p class="note"><strong>Observação:</strong> este documento frequentemente
+menciona classes e métodos que ainda não possuem material de referência disponível em <a href="{@docRoot}">developer.android.com</a>. Esses elementos de API
+são formatados em {@code code style} neste documento (sem hyperlinks). Para a
+documentação de API preliminar destes elementos, faça o download da <a href="{@docRoot}preview/download.html#docs">referência da prévia</a>.</p>
+
+<h3>Alterações importantes de comportamento</h3>
+
+<p>Caso tenha publicado anteriormente um aplicativo para Android, saiba que ele pode ser afetado
+pelas alterações na plataforma.</p>
+
+<p>Consulte <a href="behavior-changes.html">alterações de comportamento</a> para obter mais informações.</p>
+
+<h2 id="app-linking">Vínculo de aplicativo</h2>
+<p>Esta prévia aprimora o sistema de intenções do Android fornecendo vínculo de aplicativo mais poderoso.
+Este recurso permite que você associe um aplicativo com um domínio de web próprio. Com base nesta
+associação, a plataforma pode determinar o aplicativo padrão a ser usado para lidar com um link da web
+em particular e ignorar a solicitação aos usuários para selecionar um aplicativo. Para aprender como implementar este aplicativo, consulte
+<a href="{@docRoot}preview/features/app-linking.html">vínculo de aplicativo</a>.
+
+<h2 id="backup">Backup automático para aplicativos</h2>
+<p>O sistema agora realiza backup automático completo de dados e restauração para aplicativos. Este comportamento
+é ativado por padrão para aplicativos com M Preview; não é necessário mais código adicional. Se
+os usuários excluírem as contas da Google, os dados de backup também serão excluídos. Para aprender como este recurso
+funciona e como configurar o backup no sistema do arquivo, consulte
+<a href="{@docRoot}preview/backup/index.html">backup automático para aplicativos</a>.</p>
+
+<h2 id="authentication">Autenticação</h2>
+<p>Esta prévia oferece novas APIs para permitir que você autentique os usuários usando digitalizadores de impressão digital em dispositivos
+suportados e verifique o quão recentemente os usuários autenticaram pela última vez usando o
+mecanismo de desbloqueio por dispositivo (como senha de tela de bloqueio). Use essas APIs em conjunto com
+o <a href="{@docRoot}training/articles/keystore.html">sistema Android Keystore</a>.</p>
+
+<h3 id="fingerprint-authentication">Autenticação com impressão digital</h3>
+
+<p>Para autenticar os usuários por meio de digitalização de impressão digital, adquira uma instância da nova classe
+{@code android.hardware.fingerprint.FingerprintManager} e chame o método
+{@code FingerprintManager.authenticate()}. O aplicativo deve ser executado em um dispositivo
+compatível com sensor de impressão digital. Deve-se implementar a interface do usuário para o fluxo de autenticação
+de impressão digital no aplicativo e usar o ícone de impressão digital padrão do Android na IU.
+O ícone de impressão digital do Android ({@code c_fp_40px.png}) é incluído no
+<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">aplicativo de exemplo</a>. Caso esteja desenvolvendo vários aplicativos que usam
+autenticação de impressão digital, observe que cada aplicativo deve autenticar a impressão digital do usuário independentemente.
+</p>
+
+<p>Para usar este recurso no aplicativo, adicione primeiro a permissão {@code USE_FINGERPRINT} no
+manifesto.</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>Para ver a implementação do aplicativo da autenticação com impressão digital, consulte o
+<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">
+ exemplo de caixa de diálogo de impressão digital</a>.</p>
+
+<p>Caso esteja testando este recurso, siga estas etapas:</p>
+<ol>
+<li>Instale o Android SDK Tools Revision 24.3, caso ainda não tenha instalado.</li>
+<li>Registre uma nova impressão digital no emulador acessando
+<strong>Configurações &gt; Segurança &gt; Impressão digital</strong> e, em seguida, siga as instruções de registro.</li>
+<li>Use um emulador para emular eventos de toque de dedo com o
+comando a seguir. Use o mesmo comando para emular os eventos de toque de impressão digital na tela de
+bloqueio ou no aplicativo.
+<pre class="no-prettyprint">
+adb -e emu finger touch &lt;finger_id&gt;
+</pre>
+<p>No Windows, talvez seja necessário executar {@code telnet 127.0.0.1 &lt;emulator-id&gt;} seguido de
+{@code finger touch &lt;finger_id&gt;}.
+</p>
+</li>
+</ol>
+
+<h3 id="confirm-credential">Confirmação de credencial</h3>
+<p>O aplicativo pode autenticar os usuários com base no quão recentemente o dispositivo foi desbloqueado pela última vez. Este
+recurso libera o usuário de ter que lembrar de senhas específicas de aplicativo extras e evita
+a necessidade de implementar a própria interface do usuário de autenticação. O aplicativo deve usar este recurso
+em conjunto com uma implementação de chave secreta ou pública para a implementação de usuário.</p>
+
+<p>Para definir uma duração de tempo limite em que a mesma chave pode ser usada novamente
+após o usuário autenticar, chame o novo método
+{@code android.security.keystore.KeyGenParameterSpec.setUserAuthenticationValidityDurationSeconds()}
+ ao definir um {@link javax.crypto.KeyGenerator} ou
+{@link java.security.KeyPairGenerator}. Este recurso funciona para operações criptográficas
+simétricas.</p>
+
+<p>Evite exibir o diálogo de nova autenticação excessivamente — os aplicativos devem tentar
+usar o objeto criptográfico primeiro e, se o tempo limite expirar, usar o método
+{@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence) createConfirmDeviceCredentialIntent()}
+ para autenticar novamente o usuário dentro do aplicativo.
+</p>
+
+<p>Para ver uma implementação de aplicativo deste recurso, consulte o
+<a href="https://github.com/googlesamples/android-ConfirmCredential" class="external-link">
+exemplo de confirmação de credencial</a>.</p>
+
+<h2 id="direct-share">Compartilhamento direto</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>Esta prévia fornece as APIs para tornar o compartilhamento intuitivo e rápido para os usuários. É possível
+definir os <em>alvos de compartilhamento direto</em> que iniciam uma atividade específica no aplicativo.
+Esses alvos de compartilhamento direto são expostos aos usuários por meio do menu <em>Compartilhar</em>. Este recurso permite que os usuários
+compartilhem conteúdos aos alvos, como contatos, dentro de outros aplicativos. Por exemplo: o alvo de compartilhamento direto
+pode iniciar uma atividade em outro aplicativo de rede social, o que permite que o usuário compartilhe o conteúdo diretamente
+para um amigo ou comunidade específica neste aplicativo.</p>
+
+<p>Para ativar os alvos de compartilhamento direto, deve-se definir uma classe que estende a classe
+{@code android.service.} <br>
+{@code chooser.ChooserTargetService}. Declare o
+{@code ChooserTargetService} no manifesto. Dentro desta declaração, especifique a permissão
+{@code BIND_CHOOSER_TARGET_SERVICE} e um filtro de intenções na ação
+{@code SERVICE_INTERFACE}.</p>
+<p>O seguinte exemplo mostra como se deve declarar o {@code ChooserTargetService} no
+manifesto.</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>Para cada atividade que quiser expor ao {@code ChooserTargetService}, adicione um elemento
+{@code &lt;meta-data&gt;} com o nome
+{@code "android.service.chooser.chooser_target_service"} no manifesto do aplicativo.
+</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">Interações por voz</h2>
+<p>
+Esta prévia fornece uma API de interação por voz que, junto com
+<a href="https://developers.google.com/voice-actions/" class="external-link">ações de voz</a>
+, permite a criação de experiências por voz nos aplicativos. Chame o método
+{@code android.app.Activity.isVoiceInteraction()} para determinar se a atividade
+foi iniciada em resposta à ação de voz. Caso tenha sido iniciada, o aplicativo pode usar a classe
+{@code android.app.VoiceInteractor} para solicitar uma confirmação de voz do usuário,
+selecionar a partir de uma lista de opções e muito mais. Para aprender mais sobre a implementação de ações de voz, consulte
+<a href="https://developers.google.com/voice-actions/interaction/" class="external-link">o site de desenvolvedor de ações de voz</a>.
+</p>
+
+<h2 id="assist">Auxiliar API</h2>
+<p>
+Esta prévia oferece uma nova maneira de usuários se envolverem com os aplicativos com um assistente. Para usar este
+recurso, o usuário deve possibilitar que o assistente use o contexto atual. Quando ativado,
+o usuário pode invocar um assistente dentro de qualquer aplicativo mantendo o botão <strong>Iniciar</strong> pressionado.</p>
+<p>O aplicativo pode optar por não compartilhar o contexto atual com o assistente configurando o sinalizador
+{@link android.view.WindowManager.LayoutParams#FLAG_SECURE}. Além do conjunto
+padrão de informações que a plataforma passa ao assistente, o aplicativo pode compartilhar
+informações adicionais usando a nova classe {@code android.app.Activity.AssistContent}.</p>
+
+<p>Para fornecer ao assistente contexto adicional do aplicativo, siga estas etapas:</p>
+
+<ol>
+<li>Implemente a interface {@link android.app.Application.OnProvideAssistDataListener}.</li>
+<li>Registre esta escuta usando
+{@link android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener) registerOnProvideAssistDataListener()}.</li>
+<li>Para fornecer informações contextuais específicas da atividade, substitua o retorno de chamada
+{@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()}
+ e, opcionalmente, o novo retorno de chamada {@code Activity.onProvideAssistContent()}.
+</ol>
+
+<h2 id="notifications">Notificações</h2>
+<p>Esta prévia adiciona as seguintes alterações de API às notificações:</p>
+<ul>
+ <li>Novo nível de filtro {@code NotificationListenerService.INTERRUPTION_FILTER_ALARMS} que corresponde
+ao modo "não perturbe" de <em>despertadores apenas</em>.</li>
+ <li>Novo valor da categoria {@code Notification.CATEGORY_REMINDER} que é usado para distinguir
+lembretes de agendamentos do usuário de outros eventos (
+{@link android.app.Notification#CATEGORY_EVENT}) e despertadores (
+{@link android.app.Notification#CATEGORY_ALARM}).</li>
+ <li>Nova classe {@code android.graphics.drawable.Icon} que pode ser anexada às notificações
+por meio dos métodos {@code Notification.Builder.setSmallIcon(Icon)} e
+{@code Notification.Builder.setLargeIcon(Icon)}.</li>
+ <li>Novo método {@code NotificationManager.getActiveNotifications()} que permite que os aplicativos
+descubram quais das notificações ainda estão ativas. Para ver uma implementação de aplicativo que usa este recurso,
+consulte o <a href="https://github.com/googlesamples/android-ActiveNotifications" class="external-link">exemplo de notificações ativas</a>.</li>
+</ul>
+
+<h2 id="bluetooth-stylus">Suporte para Bluetooth Stylus</h2>
+<p>Esta prévia fornece um suporte aprimorado para a entrada de usuário usando um Bluetooth Stylus. Os usuários podem
+parear e conectar um Bluetooth Stylus compatível com o telefone ou tablet. Quando conectado, as informações
+de posição da tela tátil são fundidas com as informações de botão e pressão do Stylus
+para fornecer um alcance maior de expressão em comparação à tela tátil sozinha. O aplicativo pode escutar o pressionar
+de botões do Stylus e realizar ações secundárias registrando os novos retornos de chamada
+{@code View.onStylusButtonPressListener} e {@code GestureDetector.OnStylusButtonPressListener}
+ na atividade.</p>
+
+<p>Use as constantes e os métodos {@link android.view.MotionEvent} para detectar as interações
+de botão do Stylus:</p>
+<ul>
+<li>Se o usuário toca no Stylus com um botão na tela do aplicativo, o método
+{@link android.view.MotionEvent#getToolType(int) getTooltype()} retorna
+{@link android.view.MotionEvent#TOOL_TYPE_STYLUS}.</li>
+<li>Para aplicativos com M Preview, o método
+{@link android.view.MotionEvent#getButtonState() getButtonState()}
+ retorna {@code MotionEvent.STYLUS_BUTTON_PRIMARY} quando o usuário
+pressiona o botão principal do Stylus. Se o Stylus tiver um segundo botão, o mesmo método retorna
+{@code MotionEvent.STYLUS_BUTTON_SECONDARY} quando o usuário o pressiona. Se o usuário pressiona
+os dois botões simultaneamente, o método retorna os valores com OR juntos (
+{@code STYLUS_BUTTON_PRIMARY|STYLUS_BUTTON_SECONDARY}).</li>
+<li>
+Para aplicativos com uma versão de plataforma inferior , o método
+{@link android.view.MotionEvent#getButtonState() getButtonState()} retorna
+{@link android.view.MotionEvent#BUTTON_SECONDARY} (para o pressionar do botão principal do Stylus),
+{@link android.view.MotionEvent#BUTTON_TERTIARY} (para o pressionar do botão secundário do Stylus) ou ambos.
+</li>
+</ul>
+
+<h2 id="ble-scanning">Digitalização de baixa energia por Bluetooth aprimorada</h2>
+<p>
+Se o aplicativo realizar digitalizações de baixa energia por Bluetooth, é possível usar o novo método
+{@code android.bluetooth.le.ScanSettings.Builder.setCallbackType()} para especificar
+que você quer que os retornos de chamada sejam notificados apenas quando um pacote de propaganda correspondente ao conjunto
+{@link android.bluetooth.le.ScanFilter} for encontrado primeiro e quando
+ele não for visto por um período. Esta abordagem de digitalização é mais eficiente
+do que a fornecida na versão anterior da plataforma.
+</p>
+
+<h2 id="hotspot">Suporte a Hotspot 2.0 Release 1</h2>
+<p>
+Esta prévia adiciona suporte ao Hotspot 2.0 Release 1 nos dispositivos Nexus 6 e Nexus 9. Para fornecer
+as credenciais de Hotspot 2.0 no aplicativo, use os novos métodos da classe
+{@link android.net.wifi.WifiEnterpriseConfig}, como {@code setPlmn()} e
+{@code setRealm()}. No objeto {@link android.net.wifi.WifiConfiguration}, é possível definir os campos
+{@link android.net.wifi.WifiConfiguration#FQDN} e {@code providerFriendlyName}.
+A nova propriedade {@code ScanResult.PasspointNetwork} indica se uma rede detectada representa
+um ponto de acesso Hotspot 2.0.
+</p>
+
+<h2 id="4K-display">Modo de exibição 4K</h2>
+<p>A plataforma agora permite que aplicativos solicitem que a resolução seja aprimorada para renderização 4K
+em hardware compatível. Para consultar a resolução física atual, use as novas APIs
+{@code android.view.Display.Mode}. Se a IU for desenhada em uma resolução lógica
+menor e for redimensionada para uma resolução física maior, saiba que a resolução física que o método
+{@code Display.Mode.getPhysicalWidth()} retorna pode ser diferente da resolução
+física informada por {@link android.view.Display#getSize(android.graphics.Point) getSize()}.</p>
+
+<p>É possível solicitar que o sistema altere a resolução física no aplicativo à medida que ele é executado configurando
+a propriedade {@code WindowManager.LayoutParams.preferredDisplayModeId} da janela do aplicativo. Este
+recurso é útil se quiser alternar para a resolução de exibição 4K. Enquanto estiver no modo de exibição 4K,
+a IU continua a ser renderizada na resolução original (como 1080 p) e é escalonada para 4K, mas os objetos
+{@link android.view.SurfaceView} podem exibir o conteúdo na resolução nativa.</p>
+
+<h2 id="behavior-themeable-colorstatelists">ColorStateLists com tema</h2>
+<p>Os atributos de tema agora são suportados no
+{@link android.content.res.ColorStateList} para dispositivos que executam o M Preview. Os métodos
+{@link android.content.res.Resources#getColorStateList(int) getColorStateList()} e
+{@link android.content.res.Resources#getColor(int) getColor()} ficaram obsoletos. Caso esteja chamando
+essas APIs, chame os novos métodos {@code Context.getColorStateList()} ou
+{@code Context.getColor()}. Esses métodos também estão disponíveis na biblioteca
+v4 appcompat via {@link android.support.v4.content.ContextCompat}.</p>
+
+<h2 id="audio">Recursos de áudio</h2>
+
+<p>Esta prévia adiciona aprimoramentos ao processamento de áudio no Android, incluindo: </p>
+<ul>
+ <li>Suporte para protocolo <a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a>
+, com as novas APIs {@code android.media.midi}. Use essas APIs para enviar e receber eventos
+de MIDI.</li>
+ <li>Use as novas classes {@code android.media.AudioRecord.Builder} e {@code android.media.AudioTrack.Builder}
+ para criar captura de áudio digital e objetos de reprodução, respectivamente,
+e configure a fonte de áudio e as propriedades do coletor para substituir os padrões do sistema.</li>
+ <li>Ganchos de API para associação de dispositivos de entrada e áudio. Isto é particularmente útil se o aplicativo
+permite que os usuários iniciem uma pesquisa de voz a partir de um controle de jogo ou controle remoto para Android
+TV. O sistema invoca o novo retorno de chamada {@code android.app.Activity.onSearchRequested()} quando
+o usuário inicia uma pesquisa. Para determinar se o dispositivo de entrada do usuário tem um microfone integrado, recupere
+o objeto {@link android.view.InputDevice} deste retorno de chamada e, em seguida, chame o novo método
+{@code InputDevice.hasMic()}.</li>
+ <li>Novas classes {@code android.media.AudioDevicesManager} que permitem que você
+recupere uma lista completa de todas as fontes e dispositivos de áudio do coletor anexados. Também é possível especificar um objeto
+{@code android.media.OnAudioDeviceConnectionListener} caso queira que o aplicativo seja notificado
+quando um dispositivo de áudio for conectado ou desconectado.</li>
+</ul>
+
+<h2 id="video">Recursos de vídeo</h2>
+<p>Esta prévia adiciona novas capacidades às APIs de processamento de vídeo, incluindo:</p>
+<ul>
+<li>A nova classe {@code android.media.MediaSync} que ajuda os aplicativos a renderizar transmissões
+de vídeo e áudio sincronizadamente. Os buffers de áudio são enviados sem bloqueio e retornados
+por um retorno de chamada. Eles também suportam taxa de reprodução dinâmica.
+</li>
+<li>O novo evento {@code MediaDrm.EVENT_SESSION_RECLAIMED}, que indica que uma sessão aberta pelo aplicativo
+foi recuperada pelo gerenciador de recursos. Se o aplicativo usa sessões de DRM, deve-se
+lidar com este evento e garantir que uma sessão recuperada não seja usada.
+</li>
+<li>O novo código de erro {@code MediaCodec.CodecException.ERROR_RECLAIMED}, que indica que o gerenciador
+de recurso recuperou o recurso de mídia usado pelo codec. Com esta exceção, o codec
+deve ser liberado, como se fosse movido para o estado terminal.
+</li>
+<li>A nova interface {@code MediaCodecInfo.CodecCapabilities.getMaxSupportedInstances()} para obter
+uma dica do número máximo suportado de instâncias de codec concorrentes.
+</li>
+<li>O novo método {@code MediaPlayer.setPlaybackParams()} para definir a taxa de reprodução de mídia
+para reprodução de movimento lento ou rápido. Ele também estica ou acelera a reprodução de áudio automaticamente
+em conjunto com o vídeo.</li>
+</ul>
+
+<h2 id="camera">Recursos de câmera</h2>
+<p>Esta prévia inclui as seguintes novas APIs para acessar a lanterna da câmera
+e para o reprocessamento da câmera de imagens:</p>
+
+<h3 id="flashlight">API da lanterna</h3>
+<p>Se um dispositivo de câmera tem uma unidade de flash, é possível chamar o método {@code CameraManager.setTorchMode()}
+para ligar ou desligar o modo de tocha da unidade de flash sem abrir o dispositivo da câmera. O aplicativo
+não tem propriedade exclusiva da unidade de flash ou do dispositivo de câmera. O modo de tocha é desativado
+e torna-se indisponível sempre que o dispositivo de câmera estiver indisponível ou quando outros
+recursos de câmera que mantêm a tocha ativada ficam indisponíveis. Outros aplicativos também podem chamar {@code setTorchMode()}
+para desativar o modo de tocha. Quando o aplicativo que ativou o modo
+de tocha for fechado, o modo é desativado.</p>
+
+<p>É possível registrar um retorno de chamada para ser notificado sobre o estado da tocha chamando o método
+{@code CameraManager.registerTorchCallback()}. Na primeira vez que o retorno de chamada é registrado,
+ele é imediatamente chamado com o estado do modo de tocha de todos os dispositivos de câmera conhecidos com
+uma unidade de flash. Se o modo de tocha é ativado ou desativado, o método
+{@code CameraManager.TorchCallback.onTorchModeChanged()} é invocado.</p>
+
+<h3 id="reprocessing">API de reprocessamento</h3>
+<p>A API {@link android.hardware.camera2 Camera2} é estendida para suportar YUV e reprocessamento
+de imagem de formato opaco privado. O aplicativo determina se as capacidades de reprocessamento estão disponíveis
+via {@code CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES}. Se um dispositivo suporta o reprocessamento,
+é possível criar uma sessão de captura de câmera de reprocessamento chamando
+{@code CameraDevice.createReprocessableCaptureSession()} e criando solicitações para o reprocessamento
+do buffer de entrada.</p>
+
+<p>Use a classe {@code ImageWriter} para conectar o fluxo de buffer de entrada à entrada de reprocessamento
+da câmera. Para obter um buffer vazio, siga este modelo de programação:</p>
+
+<ol>
+<li>Chame o método {@code ImageWriter.dequeueInputImage()}.</li>
+<li>Preencha os dados no buffer de entrada.</li>
+<li>Envie o buffer à câmera chamando o método {@code ImageWriter.queueInputImage()}.</li>
+</ol>
+
+<p>Caso esteja usando um objeto {@code ImageWriter} junto com uma imagem
+{@code android.graphics.ImageFormat.PRIVATE}, o aplicativo não poderá acessar os dados
+da imagem diretamente. Em vez disso, passe a imagem {@code ImageFormat.PRIVATE} diretamente ao
+{@code ImageWriter} chamando o método {@code ImageWriter.queueInputImage()} sem nenhuma
+cópia de buffer.</p>
+
+<p>A classe {@code ImageReader} agora suporta as transmissões de imagem
+de formato {@code android.graphics.ImageFormat.PRIVATE}. Este suporte permite que o aplicativo mantenha uma fila de imagem circular de imagens de saída
+{@code ImageReader}, selecione uma ou mais imagens e envie-as para
+{@code ImageWriter} para o reprocessamento de câmera.</p>
+
+<h2 id="afw">Recursos do Android for Work</h2>
+<p>Esta prévia inclui as seguintes novas APIs para Android for Work:</p>
+<ul>
+ <li><strong>Controles aprimorados para dispositivos de uso único e pertencentes a empresas:</strong> O dono do dispositivo
+pode controlar as seguintes configurações para aprimorar
+os dispositivos de uso único pertencentes a empresas (COSU):
+ <ul>
+ <li>Desativar ou reativar a proteção de bloqueio com o método
+{@code DevicePolicyManager.setKeyguardEnabledState()}.</li>
+ <li>Desativar ou reativar a barra de status (incluindo configurações rápidas,
+notificações e o gesto de arrastar para cima que inicia o Google Now) com o método
+{@code DevicePolicyManager.setStatusBarEnabledState()}.</li>
+ <li>Desativar ou reativar inicialização segura com a constante {@link android.os.UserManager}
+{@code DISALLOW_SAFE_BOOT}.</li>
+ <li>Evitar que a tela desligue quando conectada com a constante
+{@link android.provider.Settings.Global} {@code STAY_ON_WHILE_PLUGGED_IN}.</li>
+ </ul>
+ </li>
+ <li><strong>Instalação e desinstalação silenciosa de aplicativos pelo dono do dispositivo:</strong> O dono do dispositivo pode agora
+instalar e desinstalar aplicativos silenciosamente usando as APIs {@link android.content.pm.PackageInstaller},
+independente do Google Play for Work. É possível tomar providências para os dispositivos
+por meio de um dono do dispositivo que recupera e instala aplicativos se a interação de usuário. Este recurso é útil para ativar a provisão de um toque
+de telefones públicos ou de outros dispositivos sem a ativação da conta Google.</li>
+<li><strong>Acesso silencioso de certificado empresarial: </strong> Quando um aplicativo chama
+{@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()}
+, antes do usuário receber a solicitação para selecionar um certificado, o perfil ou dono do dispositivo
+pode chamar o método {@code DeviceAdminReceiver.onChoosePrivateKeyAlias()} para fornecer
+o alias silenciosamente ao aplicativo da solicitação. Este recurso permite que você forneça acesso de aplicativos gerenciados para certificados
+sem a interação de usuário.</li>
+<li><strong>Aceitação automática de atualizações do sistema.</strong> Ao configurar a política de atualização do sistema com
+{@code DevicePolicyManager.setSystemUpdatePolicy()}, o dono do dispositivo pode aceitar automaticamente a atualização
+do sistema, no caso de um dispositivo público, ou adiar a atualização e evitar
+que ela seja feita pelo usuário por até 30 dias. Além disso, um administrador pode definir uma janela de tempo diária
+em que uma atualização deve ser realizada. Por exemplo: durante os momentos em que um dispositivo público não está em uso. Quando
+uma atualização do sistema está disponível, o sistema verifica se o aplicativo de controlador de política de trabalho definiu uma política de atualização
+do sistema e, portanto, comporta-se de acordo com a definição.
+</li>
+<li>
+<strong>Instalação de certificado delegado:</strong> Um perfil ou dono do dispositivo pode agora fornecer ao aplicativo
+de terceiros a habilidade de chamar essas APIs de gerenciamento
+de certificado de {@link android.app.admin.DevicePolicyManager}:
+<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>Proteção de redefinição de fábrica da empresa:</strong> Ao preparar um dono do dispositivo, agora é possível
+configurar parâmetros para desbloquear a proteção de redefinição de fábrica (FRP) configurando o pacote
+{@code DeviceManagerPolicy.EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS}. Um aplicativo de programador
+NFC pode fornecer estes parâmetros depois que um dispositivo for redefinido para desbloquear o FRP e preparar o dispositivo,
+sem a necessidade da conta Google anteriormente configurada. Caso não modifique esses parâmetros,
+o FRP permanece no local e evita que o dispositivo seja ativado sem as credenciais
+Google anteriormente ativadas.
+<p>Além disso, ao configurar as restrições do aplicativo nos serviços Google, o dono do dispositivo pode especificar contas
+Google alternativas para desbloquear o FRP para substituir as contas ativadas no dispositivo.</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>Rastreamento de uso de dados.</strong> Um perfil ou dono do dispositivo pode agora
+consultar as estatísticas de uso de dados visíveis em <strong>Configurações &gt; Uso de</strong> dados usando os novos métodos
+{@code android.app.usage.NetworkStatsManager}. Os donos de perfis recebem automaticamente
+a permissão para consultar os dados no perfil que gerenciam, enquanto que os donos do dispositivo têm acesso aos dados
+de uso do usuário principal gerenciado.</li>
+<li><strong>Gerenciamento de permissão de tempo de execução:</strong>
+<p>Um perfil ou dono do dispositivo pode definir uma política
+de permissão para todas as solicitações do tempo de execução de todos os aplicativos que usam
+{@code DevicePolicyManager.setPermissionPolicy()}, seja para solicitar ao usuário para conceder
+a permissão como normal ou automaticamente conceder ou negar a permissão silenciosamente. Se a política posterior
+for definida, o usuário não poderá modificar a seleção feita pelo perfil ou dono do dispositivo dentro da tela de permissões
+do aplicativo em <strong>configurações</strong>.</p></li>
+<li><strong>VPN em configurações:</strong> Os aplicativos de VPN agora estão visíveis em
+<strong>Configurações &gt; Mais &gt; VPN</strong>.
+Além disso, as notificações que acompanham o uso de VPN são específicas sobre como essa VPN
+é configurada. Para o dono de um perfil, as notificações são específicas para determinar
+se a VPN é configurada para um perfil gerenciado, um perfil pessoal ou ambos. Para o dono do dispositivo, as notificações
+são específicas para determinar se a VPN é configurada para todo o dispositivo.</li>
+<li><strong>Notificação de estado de trabalho:</strong> Um ícone de pasta da barra de status agora aparece
+sempre que um aplicativo do perfil gerenciado tiver uma atividade no primeiro plano. Além disso, se o usuário é desbloqueado
+diretamente para a atividade de um aplicativo no perfil gerenciado, um aviso é exibido notificando
+ao usuário que ele está dentro do perfil de trabalho.
+</li>
+</ul>
+
+<p class="note">
+ Para obter uma vista detalhada de todas as alterações de API no M Developer Preview, consulte o <a href="{@docRoot}preview/download.html">relatório de diferenças de API</a>.
+</p>
diff --git a/docs/html-intl/intl/pt-br/preview/behavior-changes.jd b/docs/html-intl/intl/pt-br/preview/behavior-changes.jd
new file mode 100644
index 0000000..cd99bbd
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/behavior-changes.jd
@@ -0,0 +1,402 @@
+page.title=Mudanças de comportamento
+page.keywords=preview,sdk,compatibility
+sdk.platform.apiLevel=MNC
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Neste documento</h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#behavior-runtime-permissions">Permissões do tempo de execução</a></li>
+ <li><a href="#behavior-power">Otimizações de economia de energia</a>
+ <ol>
+ <li><a href="#behavior-doze">Soneca</a></li>
+ <li><a href="#behavior-app-standby">Aplicativo em espera</a></li>
+ </ol>
+ </li>
+ <li><a href="#behavior-adoptable-storage">Dispositivos de armazenamento adotáveis</a></li>
+ <li><a href="#behavior-apache-http-client">Remoção do cliente Apache HTTP</a></li>
+ <li><a href="#behavior-audiomanager-Changes">Mudanças no AudioManager</a></li>
+ <li><a href="#behavior-test-selection">Seleção de texto</a></li>
+ <li><a href="#behavior-keystore">Mudanças no Android Keystore</a></li>
+ <li><a href="#behavior-network">Mudanças de rede e Wi-Fi</a></li>
+ <li><a href="#behavior-camera">Mudanças no serviço de câmera</a></li>
+ <li><a href="#behavior-art-runtime">Tempo de execução de ART</a></li>
+ <li><a href="#behavior-apk-validation">Validação de APK</a></li>
+ <li><a href="#behavior-afw">Mudanças do Android for Work</a></li>
+</ol>
+
+<h2>Diferenças de API</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">API de nível 22 para M Preview &raquo;</a> </li>
+</ol>
+
+
+<h2>Veja também</h2>
+<ol>
+<li><a href="{@docRoot}preview/api-overview.html">Visão geral da API do M Developer Preview</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>Junto com novas capacidades e recursos, o M Developer Preview inclui uma variedade
+de mudanças do sistema e alterações no comportamento da API. Este documento destaca algumas
+das alterações principais que você deve entender e levar em consideração nos aplicativos.</p>
+
+<p>Caso tenha publicado anteriormente um aplicativo para Android, saiba que ele pode ser afetado
+ pelas alterações na plataforma.</p>
+
+<h2 id="behavior-runtime-permissions">Permissões do tempo de execução</h1>
+<p>Esta prévia introduz um novo modelo de permissões em que os usuários podem gerenciar diretamente
+ as permissões do aplicativo no tempo de execução. Este modelo fornece aos usuários uma visibilidade aprimorada e controle sobre permissões,
+ ao mesmo tempo em que agiliza os processos de atualização automática e instalação para os desenvolvedores de aplicativos.
+Os usuários podem conceder ou revogar as permissões individualmente para os aplicativos instalados. </p>
+
+<p>Nos aplicativos direcionados para o M Preview, certifique-se de verificar e solicitar as permissões
+ no tempo de execução. Para determinar se o aplicativo recebeu uma permissão, chame
+ o novo método {@code Context.checkSelfPermission()}. Para solicitar uma permissão, chame o novo método
+ {@code Activity.requestPermission()}. Mesmo se o aplicativo não é direcionado para o M,
+ deve-se testá-lo sob o novo modelo de permissões.</p>
+
+<p>Para obter mais detalhes sobre o suporte do novo modelo de permissões no aplicativo, consulte a página de prévia de desenvolvedor
+<a href="{@docRoot}preview/features/runtime-permissions.html">
+Permissões</a>. Para obter dicas sobre como avaliar o impacto no aplicativo,
+ consulte o <a href="{@docRoot}preview/testing/guide.html#runtime-permissions">guia de teste</a>.</p>
+
+<h2 id="behavior-power">Otimizações de economia de energia</h2>
+<p>Esta prévia introduz novas otimizações de economia de energia para dispositivos e aplicativos ociosos.</p>
+
+<h3 id="behavior-doze">Soneca</h3>
+<p>Se o dispositivo estiver desconectado e parado com a tela desligada por um período,
+ o modo <em>Soneca</em> será ativado, onde ele tentará manter o sistema em um estado ocioso. Neste modo,
+ os dispositivos retomam as operações normais periodicamente por breves períodos para que a sincronização de aplicativos
+ possa ocorrer e para que o sistema possa realizar quaisquer operações pendentes.</p>
+
+<p>As seguintes restrições se aplicam aos aplicativos durante a Soneca:</p>
+<ul>
+<li>O acesso à rede é desativado, a não ser que o aplicativo receba um convite de alta prioridade
+ do Google Cloud Messaging.</li>
+<li><a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">Bloqueios de soneca</a> são ignorados.</li>
+<li>Os despertadores agendados com a classe {@link android.app.AlarmManager} são ignorados,
+ exceto os alarmes definidos com o método {@link android.app.AlarmManager#setAlarmClock setAlarmClock()}
+ e {@code AlarmManager.setAndAllowWhileIdle()}.</li>
+<li>As verificações de Wi-Fi não são realizadas.</li>
+<li>Sincronizações e trabalhos para os adaptadores de sincronização e {@link android.app.job.JobScheduler}
+ não têm permissão para serem executados.</li>
+</ul>
+</p>
+<p>Quando o dispositivo sair do modo soneca, quaisquer sincronizações e trabalhos pendentes são executados.</p>
+<p>É possível testar este recurso conectando o dispositivo executando o M Preview
+ à máquina de desenvolvimento e chamando os seguintes comandos:
+</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>Observação</strong>: o próximo lançamento do
+<a href="https://developers.google.com/cloud-messaging/" class="external-link">
+Google Cloud Messaging</a> permite que você designe
+ mensagens de alta prioridade. Se o aplicativo recebe mensagens de alta prioridade do GCM,
+ um acesso breve à rede é concedido mesmo quando o dispositivo está no modo soneca.
+</p>
+
+<p>Consulte o
+<a href="{@docRoot}preview/testing/guide.html#doze-standby">guia de teste</a> para obter dicas sobre
+como testar a soneca nos aplicativos. </p>
+
+<h3 id="behavior-app-standby">Aplicativo em espera</h3>
+<p>Com esta prévia, o sistema pode determinar quais aplicativos estão em espera quando
+não estão em uso ativo. O aplicativo é considerado em espera após um período, a não ser que o sistema detecte
+algum destes sinais:</p>
+
+<ul>
+<li>O aplicativo foi explicitamente iniciado pelo usuário.</li>
+<li>O aplicativo tem um processo atualmente em primeiro plano (seja uma atividade ou serviço de primeiro plano
+ ou esteja em uso por outra atividade ou serviço de primeiro plano).</li>
+<li>O aplicativo gera uma notificação que o usuário vê na tela de bloqueio
+ ou na bandeja de notificações.</li>
+<li>O usuário explicitamente pede para que o aplicativo seja liberado das otimizações,
+ ajustado em <strong>Settings (Configurações)</strong>.</li>
+</ul>
+
+<p>Se o dispositivo estiver desconectado, o aplicativo considerado ocioso terá o acesso
+à rede desativado e as sincronizações e os trabalhos suspensos. Quando o dispositivo está conectado em uma fonte de alimentação,
+ esses aplicativos têm acesso à rede permitido e podem executar quaisquer sincronizações e trabalhos pendentes. Se o dispositivo permanece ocioso por longos períodos,
+ os aplicativos ociosos têm acesso à rede permitido aproximadamente uma vez por dia.</p>
+
+<p>É possível testar este recurso conectando o dispositivo executando o M Preview
+ à máquina de desenvolvimento e chamando os seguintes comandos:
+</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>Observação</strong>: o próximo lançamento do
+<a href="https://developers.google.com/cloud-messaging/" class="external-link">
+Google Cloud Messaging</a> (GCM) permite que você
+designe mensagens de alta prioridade. Se o aplicativo recebe mensagens de alta prioridade do GCM,
+um acesso breve à rede é concedido mesmo quando o aplicativo está ocioso.
+</p>
+
+<p>Consulte o
+<a href="{@docRoot}preview/testing/guide.html#doze-standby">guia de teste</a> para obter dicas sobre como
+testar a espera dos aplicativos. </p>
+
+<h2 id="behavior-adoptable-storage">Dispositivos de armazenamento adotáveis</h2>
+<p>
+Com esta prévia, os usuários podem <em>adotar</em> dispositivos de armazenamento externo como cartões SD. Adotar um dispositivo
+de armazenamento externo criptografa e formata o dispositivo para agir como um armazenamento interno. Este recurso
+permite que os usuários movam aplicativos e dados privados desses aplicativos entre dispositivos de armazenamento. Ao mover aplicativos,
+o sistema respeita a preferência
+<a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code android:installLocation}</a>
+no manifesto.</p>
+
+<p>Se o aplicativo acessar as seguintes APIs ou campos, saiba que os caminhos de arquivos retornados
+serão alterados dinamicamente quando o aplicativo for movido entre os dispositivos de armazenamento externo e interno.
+Ao compilar caminhos de arquivos, é recomendado que essas APIs sempre sejam chamadas dinamicamente.
+Não use caminhos de arquivo criptografados nem persista em caminhos de arquivo completamente qualificados que foram compilados anteriormente.</p>
+
+<ul>
+<li>Métodos {@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>Campos {@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>Para depurar este recurso na prévia de desenvolvedor, é possível ativar a adoção
+de uma unidade USB que está conectada a um dispositivo Android por meio de um cabo USB On-The-Go (OTG) executando este comando:</p>
+
+<pre class="no-prettyprint">
+$ adb shell sm set-force-adoptable true
+</pre>
+
+<h2 id="behavior-apache-http-client">Remoção do cliente Apache HTTP</h2>
+<p>Esta prévia remove o suporte para o cliente Apache HTTP. Se o aplicativo estiver usando este cliente e for direcionado
+para Android 2.3 (nível da API 9) ou mais recente, use
+a classe {@link java.net.HttpURLConnection}. Esta API é mais eficiente, pois reduz o uso de rede por meio de compressão transparente e armazenamento
+em cachê de respostas, além de minimizar o consumo de energia. Para continuar usando as APIs do Apache HTTP,
+deve-se primeiro declarar a dependência de tempo de compilação no arquivo {@code build.gradle}:
+</p>
+<pre>
+android {
+ useLibrary 'org.apache.http.legacy'
+}
+</pre>
+<p>O Android está mudando da biblioteca OpenSSL para
+<a href="https://boringssl.googlesource.com/boringssl/" class="external-link">BoringSSL</a>
+. Caso esteja usando o Android NDK no aplicativo, não vincule contra bibliotecas criptográficas
+que não fazem parte da API de NDK, como {@code libcrypto.so} e {@code libssl.so}. Estas bibliotecas não são APIs públicas
+e podem mudar ou apresentar erros sem notificar entre liberações e dispositivos.
+Além disso, você pode se expor a vulnerabilidades de segurança. Em vez disso,
+modifique o código nativo para chamar as APIs de criptografia Java via JNI ou para vincular estaticamente
+com relação a uma biblioteca criptográfica de sua escolha.</p>
+
+<h2 id="behavior-audiomanager-Changes">Mudanças no AudioManager</h2>
+<p>Ajustar o volume diretamente ou desativar o áudio de transmissões específicas por meio da classe {@link android.media.AudioManager}
+não são mais recursos suportados. O método {@link android.media.AudioManager#setStreamSolo(int,boolean)
+setStreamSolo()} é obsoleto e deve-se chamar o método
+{@code AudioManager.requestAudioFocus()}. De forma semelhante, o método
+{@link android.media.AudioManager#setStreamMute(int,boolean) setStreamMute()} é
+obsoleto; em vez disso, chame o método {@code AudioManager.adjustStreamVolume()}
+e passe o valor da direção de {@code ADJUST_MUTE} ou {@code ADJUST_UNMUTE}.</p>
+
+<h2 id="behavior-test-selection">Seleção de texto</h2>
+
+<img src="{@docRoot}preview/images/text-selection.gif" style="float:right; margin:0 0 20px 30px" width="360" height="640" />
+
+<p>Quando os usuários selecionam o texto no aplicativo, agora é possível exibir ações de seleção de texto como
+<em>Recortar</em>, <em>Copiar</em> e <em>Colar</em> na
+<a href="http://www.google.com/design/spec/patterns/selection.html#selection-text-selection" class="external-link">barra de ferramentas flutuante</a>. A implementação da interação do usuário é semelhante ao processo
+da barra de ação contextual, como descrito em
+<a href="{@docRoot}guide/topics/ui/menus.html#CABforViews">
+Ativação do modo de ação contextual para vistas individuais</a>.</p>
+
+<p>Para implementar uma barra de ferramentas flutuante para seleção de texto, faça as seguintes alterações nos aplicativos
+existentes:</p>
+<ol>
+<li>No objeto {@link android.view.View} ou {@link android.app.Activity}, altere as chamadas
+{@link android.view.ActionMode} de
+{@code startActionMode(Callback)} para {@code startActionMode(Callback, ActionMode.TYPE_FLOATING)}.</li>
+<li>Pegue a implementação existente de {@code ActionMode.Callback} e torne-a uma extensão de
+{@code ActionMode.Callback2}.</li>
+<li>Substitua o método {@code Callback2.onGetContentRect()} para fornecer as coordenadas do conteúdo
+do objeto {@link android.graphics.Rect} (como um retângulo de seleção de texto) na vista.</li>
+<li>Se o posicionamento do retângulo deixar de ser válido e for o único elemento a ser invalidado,
+chame o método {@code ActionMode.invalidateContentRect()}.</li>
+</ol>
+
+<p>Caso esteja usando a <a href="{@docRoot}tools/support-library/index.html">
+biblioteca de suporte Android</a> revisão 22.2, saiba que as barras de ferramentas flutuantes não
+têm compatibilidade com versões anteriores e que o appcompat tem controle sobre os objetos {@link android.view.ActionMode} por
+padrão. Isto evita que barras de ferramentas flutuantes sejam exibidas. Para ativar o suporte de
+{@link android.view.ActionMode} em um
+{@link android.support.v7.app.AppCompatActivity}, chame
+{@code android.support.v7.app.AppCompatActivity.getDelegate()} e, em seguida, chame
+{@code android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled()} no objeto
+{@link android.support.v7.app.AppCompatDelegate} retornado e defina
+o parâmetro de entrada para {@code false}. Esta chamada retorna o controle dos objetos {@link android.view.ActionMode}
+à estrutura. Em dispositivos que são executados no M Preview, isto permite que a estrutura suporte os modos de
+{@link android.support.v7.app.ActionBar} ou de barra de ferramenta flutuante, enquanto que, para dispositivos anteriores ao M Preview,
+somente os modos {@link android.support.v7.app.ActionBar} são suportados.</p>
+
+<h2 id="behavior-keystore">Mudanças no Android Keystore</h2>
+<p>Com esta prévia,
+o <a href="{@docRoot}training/articles/keystore.html">provedor Android Keystore</a> não suporta mais
+DSA. ECDSA ainda é suportado.</p>
+
+<p>As chaves que não exigem criptografia em rest não precisam ser excluídas quando a tela de bloqueio segura
+é desativada ou redefinida (por exemplo, pelo usuário ou por um administrador do dispositivo). As chaves que exigem
+criptografia serão excluídas durante esses eventos.</p>
+
+<h2 id="behavior-network">Mudanças de rede e Wi-Fi</h2>
+
+<p>Esta prévia introduz as seguintes alterações de comportamento nas APIs de rede e Wi-Fi.</p>
+<ul>
+<li>Os aplicativos podem alterar o estado dos objetos {@link android.net.wifi.WifiConfiguration}
+somente se você os tiver criado. Você não tem permissão para modificar nem excluir objetos
+{@link android.net.wifi.WifiConfiguration} criados pelo usuário ou outros aplicativos.
+</li>
+<li>
+Anteriormente, se um aplicativo forçasse o dispositivo a se conectar a uma rede Wi-Fi específica usando
+{@link android.net.wifi.WifiManager#enableNetwork(int,boolean) enableNetwork()} com a configuração
+{@code disableAllOthers=true}, o dispositivo desconectava de outras redes,
+como dados de celular. Nesta prévia, o dispositivo não rompe a conexão com outras redes. Se
+o {@code targetSdkVersion} do aplicativo for {@code “20”} ou menor, ele é fixado
+à rede Wi-Fi selecionada. Se o {@code targetSdkVersion} do aplicativo for {@code “21”} ou maior, use
+as APIS de multi-rede (como
+{@link android.net.Network#openConnection(java.net.URL) openConnection()},
+{@link android.net.Network#bindSocket(java.net.Socket) bindSocket()} e o novo método
+{@code ConnectivityManager.bindProcessToNetwork()}) para garantir que o tráfego de rede
+seja enviado na rede selecionada.</li>
+</ul>
+
+<h2 id="behavior-camera">Mudanças no serviço de câmera</h2>
+<p>Nesta prévia, o modelo para acessar recursos compartilhados no serviço de câmera foi alterado
+do antigo modelo de acesso “primeiro a chegar, primeiro a ser atendido” para um modelo de acesso onde
+os processos de alta prioridade são favorecidos. As mudanças no comportamento do serviço incluem:</p>
+<ul>
+<li>Acesso aos recursos do subsistema da câmera, incluindo abertura e configuração de um dispositivo de câmera,
+concedido com base na prioridade do processo do aplicativo do cliente. Processos de aplicativos com atividades
+visíveis ao usuário ou de primeiro plano são geralmente de alta prioridade, tornando a aquisição
+e o uso de recursos da câmera mais dependentes.</li>
+<li>Clientes de câmera ativa para aplicativos de menor prioridade podem ser "despejados" quando
+um aplicativo de alta prioridade tenta usar a câmera. Na API {@link android.hardware.Camera} obsoleta,
+isto resulta em
+{@link android.hardware.Camera.ErrorCallback#onError(int,android.hardware.Camera) onError()} sendo
+chamado para o cliente despejado. Na API {@link android.hardware.camera2 Camera2}, isto resulta em
+{@link android.hardware.camera2.CameraDevice.StateCallback#onDisconnected(android.hardware.camera2.CameraDevice) onDisconnected()}
+sendo chamado para o cliente despejado.</li>
+<li>Em dispositivos com hardware de câmera adequado, processos de aplicativo separados podem
+abrir e usar independentemente os dispositivos de câmera simultaneamente. No entanto, casos de uso de vários processos
+em que o acesso simultâneo causa uma degradação significante de desempenho ou capacidades
+de qualquer um dos dispositivos de câmera abertos agora são detectados e proibidos pelo serviço da câmera. Esta alteração
+pode resultar em "despejos" para clientes de menor prioridade quando nenhum aplicativo está
+tentando acessar o mesmo dispositivo de câmera diretamente.
+</li>
+<li>
+Alterar o usuário atual faz com que os clientes da câmera ativa em aplicativos pertencentes à conta do usuário anterior
+sejam despejados. O acesso à câmera é limitado a perfis de usuário pertencentes ao usuário do dispositivo atual.
+Na prática, isso significa que uma conta de "convidado", por exemplo, não poderá deixar
+processos em execução que usam o subsistema da câmera quando o usuário alternar para uma conta diferente.
+</li>
+</ul>
+
+<h2 id="behavior-art-runtime">Tempo de execução de ART</h2>
+<p>O tempo de execução de ART agora implementa adequadamente as regras de acesso
+para o método {@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()}. Esta
+alteração corrige um problema onde o Dalvik estava verificando as regras de acesso incorretamente em versões anteriores.
+Se o aplicativo usa o método
+{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} e você quer
+substituir as verificações de acesso, chame o método
+{@link java.lang.reflect.Constructor#setAccessible(boolean) setAccessible()} com o parâmetro
+de entrada definido como {@code true}. Se o aplicativo usar a
+<a href="{@docRoot}tools/support-library/features.html#v7-appcompat">biblioteca v7 appcompat</a> ou a
+<a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">biblioteca v7 recyclerview</a>,
+deve-se atualizá-lo para usar as versões mais recentes dessas bibliotecas. Caso contrário, certifique-se
+de que as classes personalizadas mencionadas a partir do XML sejam atualizadas para que os construtores de classe estejam acessíveis.</p>
+
+<p>Esta prévia atualiza o comportamento do vinculador dinâmico. O vinculador dinâmico agora entende
+a diferença entre um {@code soname} da biblioteca e o seu caminho
+(<a href="https://code.google.com/p/android/issues/detail?id=6670" class="external-link">
+erro público 6670</a>), e a pesquisa por {@code soname}
+agora está implementada. Os aplicativos que anteriormente trabalhavam e têm entradas {@code DT_NEEDED} inválidas
+(geralmente, caminhos absolutos no sistema de arquivo na máquina de programação) podem falhar ao serem carregados.</p>
+
+<p>O sinalizador {@code dlopen(3) RTLD_LOCAL} agora está corretamente implementado. Observe que
+{@code RTLD_LOCAL} é o padrão. Portanto, chamadas para {@code dlopen(3)} que não usam explicitamente
+{@code RTLD_LOCAL} serão afetadas (a não ser que o aplicativo tenha usado explicitamente {@code RTLD_GLOBAL}). Com
+{@code RTLD_LOCAL}, os símbolos não estarão disponíveis para as bibliotecas carregadas por chamadas posteriores a
+{@code dlopen(3)} (o oposto ocorre quando mencionado por entradas {@code DT_NEEDED}).</p>
+</p>
+
+<h2 id="behavior-apk-validation">Validação de APK</h2>
+<p>A plataforma agora realiza validações mais estritas de APKs. Um APK é considerado corrompido se um arquivo
+for declarado no manifesto, mas não estiver presente no próprio APK. Um APK deve ser atribuído novamente se qualquer
+conteúdo for removido.</p>
+
+<h2 id="behavior-afw">Mudanças do Android for Work</h2>
+<p>Esta prévia inclui as seguintes mudanças de comportamento para Android for Work:</p>
+<ul>
+<li><strong>Contatos de trabalho em contextos pessoais.</strong> O registro de chamadas do telefone do Google
+agora exibe os contatos de trabalho quando o usuário visualiza chamadas anteriores.
+A configuração {@code DevicePolicyManager.setCrossProfileCallerIdDisabled()} para {@code true} oculta
+os contatos do perfil de trabalho no registro de chamadas do telefone. Os contatos de trabalho podem ser exibidos junto com os contatos pessoais
+aos dispositivos por meio de Bluetooth somente
+se {@code DevicePolicyManager.setBluetoothContactSharingDisabled()} estiver definido como {@code false}. Por
+padrão, ele está definido como {@code true}.
+</li>
+<li><strong>Remoção de configuração Wi-Fi:</strong> as configurações de Wi-Fi adicionadas por um dono de perfil
+(por exemplo, por meio de chamadas para o método
+{@link android.net.wifi.WifiManager#addNetwork(android.net.wifi.WifiConfiguration)
+addNetwork()}) agora são removidas se esse perfil de trabalho é excluído.</li>
+<li><strong>Bloqueio de configuração Wi-Fi:</strong> qualquer configuração Wi-Fi criada por um dono do dispositivo
+ativo não pode mais ser modificada nem excluída pelo usuário. O usuário ainda pode criar
+e modificar as próprias configurações de Wi-Fi, contanto que a constante {@link android.os.UserManager}
+{@link android.os.UserManager#DISALLOW_CONFIG_WIFI} não tenha sido definida por ele.</li>
+<li><strong>Faça o download do Work Policy Controller por meio de uma adição de conta Google:</strong> quando uma conta Google
+que requer um gerenciamento por meio do aplicativo Work Policy Controller (WPC) é adicionada ao dispositivo
+fora de um contexto gerenciado, o fluxo de conta adicionada agora solicita ao usuário para instalar
+o WPC adequado. Este comportamento também se aplica a contas adicionadas por meio de
+<strong>Settings (Configurações) &gt; Accounts (Contas)</strong> no assistente de configuração inicial do dispositivo.</li>
+<li><strong>Alterações aos comportamentos específicos da API DevicePolicyManager:</strong>
+chamar o método {@link android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName,boolean) setCameraDisabled()}
+afeta a câmera somente para o usuário que realizou a chamada. Chamá-lo a partir do perfil gerenciado
+não afeta os aplicativos de câmera em execução no usuário principal. Além disso,
+o método {@link android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures(android.content.ComponentName,int) setKeyguardDisabledFeatures()}
+agora está disponível para donos de perfil, além dos donos do dispositivo. Um dono de perfil pode definir
+estas restrições de proteção de bloqueio:
+<ul>
+<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS} e
+ {@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_FINGERPRINT}, que afetam
+ as configurações de proteção de bloqueio para o usuário pai do perfil.</li>
+<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}, que
+ afeta somente as notificações geradas por aplicativos no perfil gerenciado.</li>
+</ul>
+</li>
+</ul>
diff --git a/docs/html-intl/intl/pt-br/preview/features/runtime-permissions.jd b/docs/html-intl/intl/pt-br/preview/features/runtime-permissions.jd
new file mode 100644
index 0000000..762e1ae
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/features/runtime-permissions.jd
@@ -0,0 +1,794 @@
+page.title=Permissões
+page.tags=previewresources, androidm
+page.keywords=permissions, runtime, preview
+page.image={@docRoot}preview/images/permissions_check.png
+@jd:body
+
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>Visualização rápida</h2>
+ <ul>
+ <li>Se o aplicativo direciona o M Preview SDK, ele indica aos usuários para conceder
+ permissões no tempo de execução, em vez de tempo de instalação.</li>
+ <li>Os usuários podem revogar as permissões a qualquer momento na tela de configurações
+do aplicativo.</li>
+ <li>O aplicativo precisa verificar se tem as permissões necessárias
+sempre que for executado.</li>
+ </ul>
+
+ <h2>Neste documento</h2>
+ <ol>
+ <li><a href="#overview">Visão geral</a></li>
+ <li><a href="#coding">Codificação para permissões de tempo de execução</a></li>
+ <li><a href="#testing">Teste de permissões de tempo de execução</a></li>
+ <li><a href="#best-practices">Práticas recomendadas</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>
+ O M Developer Preview introduz um novo modelo de permissões de aplicativo
+que agiliza o processo de instalação e atualização de aplicativos para os usuários. Se um aplicativo
+ que está sendo executado no M Preview suporta o novo modelo de permissões, o usuário não precisa conceder
+ permissões ao instalar ou atualizar o aplicativo. Em vez disso, o aplicativo
+ solicita as permissões à medida que precisar e o sistema exibe um diálogo
+ ao usuário pedindo a permissão.
+</p>
+
+<p>
+ Se um aplicativo suportar o novo modelo de permissões, ele
+ ainda poderá ser instalado e executado em versões mais antigas do Android, usando o antigo modelo
+ de permissões nesses dispositivos.
+</p>
+
+<h2 id="overview">
+ Visão geral
+</h2>
+
+<p>
+ Com o M Developer Preview, a plataforma introduz um novo modelo
+ de permissões. Eis um resumo dos componentes essenciais deste novo modelo:
+</p>
+
+<ul>
+ <li>
+ <strong>Declaração de permissões:</strong> O aplicativo declara todas
+ as permissões necessárias no manifesto, como nas plataformas anteriores do Android.
+ </li>
+
+ <li>
+ <strong>Grupos de permissão:</strong> As permissões são divididas em
+<em>grupos de permissão</em>, baseados na funcionalidade. Por exemplo: o grupo de permissão
+ <code>CONTACTS</code> contém permissões para ler e escrever
+ informações de perfil e contatos do usuário.
+ </li>
+
+ <li>
+ <p><strong>Permissões limitadas concedidas no tempo de instalação:</strong> Quando o usuário
+ instala ou atualiza o aplicativo, o sistema concede todas
+ as permissões que o aplicativo solicita que estão em {@link
+ android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}.
+ Por exemplo: as permissões de internet e despertador estão em {@link
+ android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}. Portanto,
+ as permissões são concedidas automaticamente no tempo de instalação.
+ </p>
+
+ <p>O sistema pode também conceder as permissões de sistema e assinatura de aplicativo,
+ como descrito em <a href="#system-apps">permissões de assinatura
+ e aplicativos do sistema</a>. O usuário <em>não</em> é alertado a conceder permissões
+ no tempo de instalação.</p>
+ </li>
+
+ <li>
+ <strong>O usuário concede permissões no tempo de execução:</strong> Quando um aplicativo solicita
+ uma permissão, o sistema exibe um diálogo ao usuário e, em seguida,
+ chama a função de retorno de chamada do aplicativo para notificá-lo se a permissão foi concedida. Se um
+ usuário concede uma permissão, o aplicativo recebe todas
+ as permissões na área funcional desta permissão que foram declaradas no manifesto do aplicativo.
+ </li>
+
+</ul>
+
+<p>
+ Este modelo de permissões altera a forma como o aplicativo se comporta diante os recursos
+ que precisam de permissões. Eis um resumo das práticas de desenvolvimento que devem
+ ser seguidas para ajustar para este modelo:
+</p>
+
+<ul>
+
+ <li>
+ <strong>Sempre verificar as permissões:</strong> Quando o aplicativo
+ precisa realizar uma ação que requer uma permissão, ele deve primeiro verificar
+ se já a tem. Caso não tenha, ele solicita
+ o concedimento desta permissão.
+ </li>
+
+ <li>
+ <strong>Lidar com falta de permissões dignamente:</strong> Se o aplicativo não
+ recebe a permissão adequada, ele deve lidar com a falha de forma limpa.
+ Por exemplo, se a permissão é necessária para um recurso adicionado,
+ o aplicativo pode desativar este recurso. Se a permissão for essencial
+ para que o aplicativo funcione, ele desativará toda sua funcionalidade
+ e informará ao usuário que precisa desta permissão.
+ </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>Figura 1.</strong> Tela de permissões nas configurações do aplicativo.
+ </p>
+ </div>
+
+ <li>
+ <strong>As permissões são revogáveis:</strong> Os usuários podem revogar as permissões
+ de um aplicativo a qualquer momento. Se um usuário desativar as permissões de um aplicativo,
+ o aplicativo <em>não</em> é notificado. Novamente, o aplicativo deve verificar
+ se tem todas as permissões necessárias antes de realizar qualquer ação restrita.
+ </li>
+</ul>
+
+<p class="note">
+ <strong>Observação:</strong> se um aplicativo direcionar o M Developer Preview, ele
+ <em>deve</em> usar o novo modelo de permissões.
+</p>
+
+<p>
+ No momento do lançamento do M Developer Preview,
+ nem todos os aplicativos Google implementam completamente o novo modelo de permissões. A Google está atualizando estes aplicativos
+ durante o curso do M Developer Preview para respeitar adequadamente a configuração
+ de alternação de permissões.
+</p>
+
+<p class="note">
+ <strong>Observação:</strong> se o aplicativo tiver a própria superfície de API,
+ não represente permissões sem antes garantir que o autor da chamada tenha as permissões necessárias
+ para acessar esses dados.
+</p>
+
+<h3 id="system-apps">
+ Permissões de assinatura e aplicativos do sistema
+</h3>
+
+<p>
+ Geralmente, quando um usuário instala um aplicativo, o sistema somente fornece ao aplicativo o
+ {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL
+ PROTECTION_NORMAL}. No entanto, sob algumas circunstâncias, o sistema concede
+ ao aplicativo mais permissões:
+</p>
+
+<ul>
+ <li>Se um aplicativo faz parte da imagem do sistema, ele recebe automaticamente
+ todas as permissões listadas no manifesto.
+ </li>
+
+ <li>Se o aplicativo solicitar as permissões no manifesto que está em {@link
+ android.content.pm.PermissionInfo#PROTECTION_SIGNATURE PROTECTION_SIGNATURE},
+ e estiver assinado com o mesmo certificado que o aplicativo que declarou essas permissões,
+ o sistema concederá essas permissões na instalação ao aplicativo
+ que fez a solicitação.
+ </li>
+</ul>
+
+<p>
+ Em ambos os casos, o usuário ainda pode revogar as permissões a qualquer
+ momento acessando a tela de <strong>configurações</strong> do sistema e escolhendo <strong>Aplicativos
+ &gt;</strong> <i>app_name</i> <strong>&gt; Permissões</strong>. O aplicativo
+ deve continuar com a verificação das permissões no tempo de execução e solicitá-las
+ se necessário.
+</p>
+
+<h3 id="compatibility">
+ Compatibilidade anterior e posterior
+</h3>
+
+<p>
+ Se um aplicativo não direciona para o M Developer Preview, ele deve continuar a usar
+ o modelo antigo de permissões mesmo nos dispositivos M Preview. Quando o usuário instala
+ o aplicativo, o sistema pede para que ele conceda todas as permissões
+ listadas no manifesto do aplicativo.
+</p>
+
+<p class="note">
+ <strong>Observação:</strong> em dispositivos que são executados no M Developer Preview,
+ um usuário pode desativar as permissões para qualquer aplicativo (incluindo aplicativos de legado)
+ na tela de configurações do aplicativo. Se um usuário desativa as permissões de um aplicativo de legado, o sistema
+ silenciosamente desativa a funcionalidade adequada. Quando um aplicativo tentar realizar
+ uma operação que requer esta permissão, a operação não necessariamente causará
+ uma exceção. Em vez disso, ele retornará um conjunto de dados vazio,
+ sinalizará um erro ou exibirá um comportamento inesperado. Por exemplo, caso queira
+ consultar um calendário sem permissão, o método retorna um conjunto de dados vazio.
+</p>
+
+<p>
+ Se instalar um aplicativo usando o novo modelo de permissões em um dispositivo
+ que não está executando o M Preview,
+ o sistema o tratará da mesma forma que qualquer outro aplicativo: o sistema pedirá
+ para que o usuário conceda todas as permissões declaradas no momento da instalação.
+</p>
+
+<p class="note">
+ <strong>Observação:</strong> para a liberação de prévia, deve-se definir a versão mínima de SDK
+ para o M Preview SDK para compilar com o SDK de prévia. Isto significa que você
+ não poderá testar tais aplicativos em plataformas mais antigas durante a prévia
+ de desenvolvedor.
+</p>
+
+<h3 id="perms-vs-intents">Permissões versus intenções</h3>
+
+<p>
+ Em vários casos, é possível escolher entre duas maneiras para que o aplicativo realize
+ uma tarefa. É possível fazer com que o aplicativo solicite uma permissão para realizar a operação
+ por conta própria. Alternativamente, é possível fazer com que o aplicativo use uma intenção para que outro aplicativo
+ realize a tarefa.
+</p>
+
+<p>
+ Por exemplo, imagine que o aplicativo precisa da função de tirar fotos com
+ a câmera do dispositivo. O aplicativo pode solicitar a permissão
+<code>android.permission.CAMERA</code>, que permite que ele acesse
+ a câmera diretamente. O aplicativo então usará as APIs da câmera
+ para controlar a câmera e tirar uma foto. Esta abordagem fornece ao aplicativo
+ controle completo sobre o processo de fotografia e permite
+ que você incorpore a IU da câmera.
+</p>
+
+<p>
+ No entanto, caso não precise de tal controle, é possível apenas usar uma intenção {@link
+ android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE}
+ para solicitar uma imagem. Ao iniciar a intenção, o usuário deve escolher
+ um aplicativo de câmera (se não houver um aplicativo padrão de câmera)
+ para tirar a foto. O aplicativo da câmera retorna a imagem ao método {@link
+ android.app.Activity#onActivityResult onActivityResult()} do aplicativo.
+</p>
+
+<p>
+ De forma semelhante, caso precise realizar uma ligação,
+ acessar os contatos do usuário etc., é possível fazer estas ações criando uma intenção adequada
+ ou solicitar a permissão e o acesso aos objetos adequados diretamente. Essas são
+ as vantagens e desvantagens de cada abordagem.
+</p>
+
+<p>
+ Se usar permissões:
+</p>
+
+<ul>
+ <li>O aplicativo tem controle completo sobre a experiência do usuário ao realizar
+ a operação. No entanto, esse controle amplo é adicionado à complexidade da tarefa,
+ levando em consideração a necessidade de projetar uma IU adequada.
+ </li>
+
+ <li>O usuário deve fornecer a permissão uma vez: na primeira realização
+ da operação. Depois, o aplicativo pode realizar a operação sem
+ precisar de mais interações do usuário. No entanto,
+ se o usuário não conceder a permissão (ou revogá-la posteriormente),
+ o aplicativo não conseguirá realizar a operação.
+ </li>
+</ul>
+
+<p>
+ Se usar uma intenção:
+</p>
+
+<ul>
+ <li>Você não terá que projetar a IU para a operação. O aplicativo que lida com
+ a intenção fornece a IU. No entanto, isso significa que você não terá controle
+ completo sobre a experiência de usuário. O usuário poderá interagir com um aplicativo
+ que você nunca viu.
+ </li>
+
+ <li>Se o usuário não tem um aplicativo padrão para a operação,
+ o sistema pede para que o usuário escolha um aplicativo.
+ Se o usuário não designar um manipulador padrão,
+ ele terá que acessar uma caixa de diálogo extra sempre que realizar a operação.
+ </li>
+</ul>
+
+<h2 id="coding">Codificação para permissões de tempo de execução</h2>
+
+<p>
+ Se um aplicativo direciona o novo M Developer Preview, ele deve usar o novo
+ modelo de permissões. Isto significa que, além de declarar as permissões necessárias no manifesto,
+ deve-se também verificar se o aplicativo
+ tem as permissões no tempo de execução e,
+ caso ainda não as tenha, solicitá-las.
+</p>
+
+<h3 id="enabling">
+ Possibilitar um novo modelo de permissões
+</h3>
+
+<p>
+ Para possibilitar o modelo de permissões do M Developer Preview, configure o atributo
+<code>targetSdkVersion</code> do aplicativo para <code>"MNC"</code> e
+<code>compileSdkVersion</code> para <code>"android-MNC"</code>. Isto ativará
+ todos os novos recursos de permissão.
+</p>
+
+<p>
+ Para a liberação de uma prévia, deve-se definir <code>minSdkVersion</code> para
+<code>"MNC"</code> para compilar com o SDK de prévia.
+</p>
+
+<h3 id="m-only-perm">
+ Designar uma permissão somente para o M Preview
+</h3>
+
+<p>
+ É possível usar o novo elemento <code>&lt;uses-permission-sdk-m&gt;</code> no manifesto do aplicativo
+ para indicar que uma permissão é necessária apenas no M Developer Preview. Se você
+ declarar uma permissão desta maneira, sempre que o aplicativo for instalado
+ em um dispositivo mais antigo, o sistema não solicitará ao usuário
+ nem concederá a permissão ao aplicativo. Usando o elemento <code>&lt;uses-permission-sdk-m&gt;</code>
+, é possível adicionar novas permissões
+ a versões atualizadas do aplicativo sem forçar os usuários a conceder permissões
+ ao instalar a atualização.
+</p>
+
+<p>
+ Se o aplicativo está sendo executado em um dispositivo com M Developer Preview, o
+<code>&lt;uses-permission-sdk-m&gt;</code> se comporta da mesma forma que
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>.
+ O sistema não solicita ao usuário que conceda quaisquer permissões ao instalar o aplicativo
+ e o aplicativo solicita as permissões à medida que forem necessárias.
+</p>
+
+<h3 id="prompting">
+ Solicitação de permissões
+</h3>
+
+<p>
+ Se o aplicativo usa o novo modelo de permissões do M Developer Preview,
+ o usuário não recebe solicitações para conceder todas as permissões quando o aplicativo é iniciado pela primeira vez em um dispositivo
+ que está sendo executado no M Preview. Em vez disso, o aplicativo solicita as permissões à medida
+ que forem necessárias. Quando um aplicativo solicita uma permissão, o sistema exibe uma caixa de diálogo
+ ao usuário.
+</p>
+
+<p>
+ Se o aplicativo executar em um dispositivo que tem SDK 22 ou inferior,
+ ele usará o antigo modelo de permissões. Quando o usuário instala o aplicativo, ele é solicitado a conceder
+ todas as permissões que o aplicativo lista no manifesto,
+ exceto as permissões que forem marcadas com <code>&lt;uses-permission-sdk-m&gt;</code>.
+</p>
+
+<h4 id="check-platform">Verifique em qual plataforma o aplicativo está sendo executado</h4>
+
+<p>
+ Este modelo de permissões é suportado apenas em dispositivos que estão executando
+ o M Developer Preview. Antes de chamar qualquer um destes métodos,
+ o aplicativo deve verificar em qual plataforma está sendo executado
+ verificando o valor de {@link android.os.Build.VERSION#CODENAME
+ Build.VERSION.CODENAME}. Se o dispositivo estiver sendo executado no M Developer Preview,
+ {@link android.os.Build.VERSION#CODENAME CODENAME} será <code>"MNC"</code>.
+</p>
+
+<h4 id="check-for-permission">Verifique se o aplicativo tem a permissão necessária</h4>
+
+<p>Quando o usuário tenta fazer algo que requer uma permissão,
+ o aplicativo verifica se tem a permissão para realizar esta operação. Para fazer isto,
+ o aplicativo chama
+ <code>Context.checkSelfPermission(<i>permission_name</i>)</code>. O aplicativo
+ deve realizar isto para verificar se sabe que o usuário já concedeu esta permissão,
+ levando em consideração que o usuário pode revogar
+ as permissões do aplicativo a qualquer momento. Por exemplo,
+ se um usuário quiser usar um aplicativo para tirar uma foto, o aplicativo chamará
+ <code>Context.checkSelfPermission(Manifest.permission.CAMERA)</code>.</p>
+
+<p class="table-caption" id="permission-groups">
+ <strong>Tabela 1.</strong> Permissões e grupos de permissões.</p>
+<table>
+ <tr>
+ <th scope="col">Grupo de permissões</th>
+ <th scope="col">Permissões</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">Solicitar permissões se necessário</h4>
+
+<p>Se o aplicativo já não tem a permissão necessária, ele chama o método
+ <code>Activity.requestPermissions(String[], int)</code> para solicitar
+ as permissões necessárias. O aplicativo passa
+ as permissões que deseja e também um "código de solicitação" do inteiro.
+ Este método funciona de forma assíncrona: ele retorna imediatamente e,
+ depois que o usuário responde à caixa de diálogo, o sistema chama
+ o método de retorno de chamada do aplicativo com os resultados, passando o mesmo "código de solicitação" que o aplicativo passou
+ para <code>requestPermissions()</code>.</p>
+
+ <p>O seguinte código verifica se o aplicativo tem a permissão
+ para ler os contatos do usuário e solicita a permissão, se necessário:</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">Lidar com a resposta de solicitação das permissões</h4>
+
+<p>
+ Quando um aplicativo solicita as permissões, o sistema apresenta uma caixa de diálogo
+ ao usuário. Quando o usuário responde, o sistema invoca o
+ <code>Activity.onRequestPermissionsResult(int, String[], int[])</code>
+ do aplicativo, passando a ele a resposta do usuário. O aplicativo precisa substituir este método. O retorno de chamada
+ recebe o mesmo código de solicitação passado para
+ <code>requestPermissions()</code>. Por exemplo, se um aplicativo solicita o acesso
+ <code>READ_CONTACTS</code>, ele pode ter o seguinte
+ método de retorno de chamada:
+</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>Se o usuário concede a permissão, o sistema fornece ao aplicativo todas as permissões
+ que o manifesto do aplicativo lista para esta área funcional. Se o usuário negar a solicitação,
+ deve-se tomar a ação adequada. Por exemplo, deve-se desativar
+ quaisquer ações de menu que dependam desta permissão.
+ </li>
+</p>
+
+<p>
+ Quando o sistema pede para que o usuário conceda uma permissão, esse usuário tem a opção
+ de dizer ao sistema para que não peça esta permissão novamente. Nesse caso,
+ quando um aplicativo usa <code>requestPermissions()</code> para solicitar esta permissão,
+ o sistema nega imediatamente. Neste caso, o sistema chama
+ <code>onRequestPermissionsResult()</code> da mesma forma que faria se o usuário tivesse
+ rejeitado explicitamente a solicitação novamente. Por este motivo, o aplicativo
+ não pode presumir que uma interação direta com o usuário ocorreu.
+</p>
+
+<h2 id="testing">Teste de permissões de tempo de execução</h2>
+
+
+<p>
+ Se o aplicativo for direcionado para o M Developer Preview, deve-se testar
+ se ele lida com as permissões corretamente. Não se pode presumir que o aplicativo
+ terá qualquer permissão quando executado. Quando o aplicativo é iniciado pela primeira vez,
+ é provável que não tenha permissões. O usuário pode revogar e restaurar permissões
+ a qualquer momento.
+</p>
+
+<p>
+ Deve-se testar o aplicativo para garantir que ele se comporte corretamente em todas
+ as situações de permissão. Com o M Preview SDK, fornecemos os novos comandos
+ de <a href="{@docRoot}tools/help/adb.html">Android
+ Debug Bridge (adb)</a> para possibilitar que o aplicativo seja testado com quaisquer
+ configurações de permissões necessárias.
+</p>
+
+<h3>
+ Novas opções e comandos adb
+</h3>
+
+<p>
+ As ferramentas da plataforma M Preview SDK fornecem vários comandos novos para permitir
+ que você teste como o aplicativo lida com permissões.
+</p>
+
+<h4>
+ Instalar com permissões
+</h4>
+
+<p>
+ É possível usar a nova opção <code>-g</code> do comando <a href="{@docRoot}tools/help/adb.html#move"><code>adb
+ install</code></a>, que instala o aplicativo
+ e fornece todas as permissões listadas em seu manifesto:
+</p>
+
+<pre class="no-pretty-print">
+$ adb install -g &lt;path_to_apk&gt;
+</pre>
+
+<h4>
+ Conceder e revogar permissões
+</h4>
+
+<p>
+ É possível usar os novos comandos do <a href="{@docRoot}tools/help/adb.html#pm">gerenciador
+ de pacotes (pm)</a> de ADB para conceder e revogar as permissões de um aplicativo instalado.
+ Esta funcionalidade pode ser útil para testes automatizados.
+</p>
+
+<p>
+ Para conceder uma permissão, use o comando <code>grant</code> do gerenciador de pacote:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant &lt;package_name&gt; &lt;permission_name&gt;
+</pre>
+
+<p>
+ Por exemplo: para conceder a permissão do pacote com.example.myapp para gravar áudios,
+ use este comando:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO
+</pre>
+
+<p>
+ Para revogar uma permissão, use o comando <code>revoke</code> do gerenciador de pacote:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm revoke &lt;package_name&gt; &lt;permission_name&gt;
+</pre>
+
+<h2 id="best-practices">Práticas recomendadas</h2>
+
+<p>
+ O novo modelo de permissões fornece aos usuários uma experiência mais suave
+ e facilita a instalação de aplicativos, deixando-os mais confortáveis
+ com o que os aplicativos estão fazendo. Sugerimos que você siga as práticas recomendadas para aproveitar
+ todas as vantagens do novo modelo.
+</p>
+
+
+<h3 id="bp-what-you-need">Peça somente as permissões necessárias</h3>
+
+<p>
+ Sempre que você pede uma permissão, o usuário é forçado a tomar uma decisão.
+ Se o usuário negar a solicitação, a funcionalidade do aplicativo será reduzida.
+ Deve-se minimizar o número de solicitações realizadas.
+</p>
+
+<p>
+ Por exemplo: o aplicativo pode frequentemente adquirir a funcionalidade necessária usando
+ uma <a href="{@docRoot}guide/components/intents-filters.html">intenção</a> em vez
+ de solicitar permissões. Se o aplicativo precisa tirar fotos com a câmera do telefone,
+ é possível usar uma intenção {@link
+ android.provider.MediaStore#ACTION_IMAGE_CAPTURE
+ MediaStore.ACTION_IMAGE_CAPTURE}. Quando o aplicativo executa a intenção,
+ o sistema pede para que o usuário escolha um aplicativo de câmera já instalado
+ para tirar a foto.
+</p>
+
+<h3 id="bp-dont-overwhelm">
+ Não oprima o usuário
+</h3>
+
+<p>
+ Se você confrontar o usuário com várias solicitações de permissão de uma só vez,
+ é possível que ele se sinta oprimido e saia do aplicativo.
+ Em vez disso, deve-se solicitar as permissões somente quando necessário.
+</p>
+
+<p>
+ Em alguns casos, uma ou mais permissões podem ser absolutamente essenciais para o aplicativo.
+ Nesta situação, faz sentido solicitar todas as permissões assim
+ que o aplicativo é iniciado. Por exemplo: se você fizer um aplicativo de fotografia,
+ ele precisará de acesso à câmera do dispositivo. Quando o usuário iniciar o aplicativo
+ pela primeira vez, ele não se surpreenderá quando receber
+ uma solicitação de permissão para usar a câmera. Mas, se o mesmo aplicativo tiver um recurso
+ para compartilhar fotos com os contatos do usuário, <em>não</em> se deve
+ pedir esta permissão na primeira inicialização. Em vez disso, espere o usuário tentar usar
+ o recurso de compartilhamento para pedir a permissão.
+</p>
+
+<p>
+ Se o aplicativo fornecer um tutorial, faz sentido solicitar as permissões
+ necessárias no final da sequência do tutorial.
+</p>
+
+<h3 id="bp-explain">
+ Explique o porquê da necessidade das permissões
+</h3>
+
+<p>
+ O diálogo de permissões exibido pelo sistema ao chamar
+ <code>requestPermissions()</code> diz quais permissões o aplicativo requer,
+ mas não diz o porquê. Em alguns casos, o usuário pode achar isto confuso.
+ É uma boa ideia explicar ao usuário o porquê da necessidade das permissões
+ para o aplicativo antes de chamar <code>requestPermissions()</code>.
+</p>
+
+<p>
+ Por exemplo: um aplicativo de fotografia pode precisar usar serviços de localização
+ para poder marcar as fotos geograficamente. Um usuário normal pode não entender que uma foto
+ pode conter informações de localização e ficar confuso quando
+ o aplicativo de fotografia quiser saber a localização. Portanto, neste caso, é uma boa ideia o aplicativo explicar
+ ao usuário sobre este recurso <em>antes</em> de chamar
+ <code>requestPermissions()</code>.
+</p>
+
+<p>
+ Uma maneira de fazer isto é incorporar estas solicitações em um tutorial do aplicativo. O tutorial pode exibir cada um dos recursos
+ do aplicativo e, à medida que fizer isto,
+ pode também explicar quais permissões são necessárias. Por exemplo, o tutorial do aplicativo de fotografia
+ pode demonstrar os recursos de compartilhamento de fotos com os contatos e,
+ em seguida, dizer ao usuário que ele precisa fornecer as permissões
+ para que o aplicativo possa visualizar os contatos. O aplicativo pode então chamar <code>requestPermissions()</code> para solicitar
+ ao usuário este acesso. É claro que nem todos os usuários seguirão o tutorial.
+ Portanto, ainda é necessário verificar e solicitar as permissões durante
+ a operação normal do aplicativo.
+</p>
diff --git a/docs/html-intl/intl/pt-br/preview/images/direct-share-screen.png b/docs/html-intl/intl/pt-br/preview/images/direct-share-screen.png
new file mode 100644
index 0000000..a53a33e
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/direct-share-screen.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/direct-share-screen_2x.png b/docs/html-intl/intl/pt-br/preview/images/direct-share-screen_2x.png
new file mode 100644
index 0000000..87816ff
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/direct-share-screen_2x.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/fingerprint-screen.png b/docs/html-intl/intl/pt-br/preview/images/fingerprint-screen.png
new file mode 100644
index 0000000..77f9982
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/fingerprint-screen.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/fingerprint-screen_2x.png b/docs/html-intl/intl/pt-br/preview/images/fingerprint-screen_2x.png
new file mode 100644
index 0000000..4749bcf
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/fingerprint-screen_2x.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/m-preview-timeline-crop.png b/docs/html-intl/intl/pt-br/preview/images/m-preview-timeline-crop.png
new file mode 100644
index 0000000..724a6af
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/m-preview-timeline-crop.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/m-preview-timeline.png b/docs/html-intl/intl/pt-br/preview/images/m-preview-timeline.png
new file mode 100644
index 0000000..e9a339e
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/m-preview-timeline.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/perf-test-frame-latency.png b/docs/html-intl/intl/pt-br/preview/images/perf-test-frame-latency.png
new file mode 100644
index 0000000..87d1cfc
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/perf-test-frame-latency.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/perf-test-framestats.png b/docs/html-intl/intl/pt-br/preview/images/perf-test-framestats.png
new file mode 100644
index 0000000..589a923
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/perf-test-framestats.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/text-selection.gif b/docs/html-intl/intl/pt-br/preview/images/text-selection.gif
new file mode 100644
index 0000000..1d82fc6
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/text-selection.gif
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/work-profile-screen.png b/docs/html-intl/intl/pt-br/preview/images/work-profile-screen.png
new file mode 100644
index 0000000..c3e4e44
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/work-profile-screen.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/work-profile-screen_2x.png b/docs/html-intl/intl/pt-br/preview/images/work-profile-screen_2x.png
new file mode 100644
index 0000000..5dcf610
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/work-profile-screen_2x.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/overview.jd b/docs/html-intl/intl/pt-br/preview/overview.jd
new file mode 100644
index 0000000..ce5a596
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/overview.jd
@@ -0,0 +1,362 @@
+page.title=Visão geral do programa
+page.metaDescription=Boas-vindas ao Android M Developer Preview, um programa que fornece tudo que é necessário para testar e otimizar os aplicativos para a próxima versão do Android.
+page.image=images/cards/card-preview_16-9_2x.png
+page.tags="preview", "developer", "android"
+
+@jd:body
+
+<p>
+ Boas-vindas ao <strong>Android M Developer Preview</strong>, um programa que fornece
+ tudo que é necessário para testar e otimizar os aplicativos para a próxima versão
+ do Android. É de graça e você pode começar agora mesmo: basta fazer
+ o download das ferramentas M Developer Preview.
+</p>
+
+<div style="background-color:#eceff1;padding:1em;">
+<div class="wrap">
+ <div class="cols">
+ <div class="col-4of12">
+ <h5>
+ Imagens de sistema de emulador e hardware
+ </h5>
+
+ <p>
+ Execute e teste os aplicativos no Nexus 5, 6, 9 e Player (para TV), bem como
+ em emuladores.
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Código de plataforma mais recente
+ </h5>
+
+ <p>
+ Nós forneceremos várias atualizações durante a prévia. Portanto, você
+ testará de acordo com as alterações mais recentes da plataforma.
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Atualizações entregues por OTA
+ </h5>
+
+ <p>
+ É possível obter atualizações por OTA (over-the-air) ao programar o dispositivo
+ em flash para a prévia inicial.
+ </p>
+ </div>
+ </div>
+
+ <div class="cols">
+
+
+ <div class="col-4of12">
+ <h5>
+ Novos comportamentos e capacidades
+ </h5>
+
+ <p>
+ Inicie o trabalho cedo para suportar os novos comportamentos da plataforma,
+ como novo modelo de permissões de tempo de execução e recursos de economia de energia.
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Janela de prioridades para problemas informados por desenvolvedores
+ </h5>
+
+ <p>
+ Durante as primeiras semanas, nós daremos prioridade aos problemas informados
+ por desenvolvedores. Portanto, teste e forneça-nos feedback o quanto antes.
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Feedback e suporte
+ </h5>
+
+ <p>
+ Informe problemas e dê-nos feedback usando o <a href="https://code.google.com/p/android-developer-preview/">issue tracker</a>.
+ Conecte-se a outros desenvolvedores na <a href="http://g.co/dev/AndroidMDevPreview">Comunidade M&nbsp;Developer</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">
+ Linha do tempo e atualizações
+</h2>
+<img src="{@docRoot}preview/images/m-preview-timeline-crop.png" alt="Preview program timeline" id="timeline">
+<p>
+ O M Developer Preview estará em execução de 28 de maio até o Android M SDK final, que
+ disponibilizaremos brevemente antes do lançamento público durante
+ o 3º trimestre de 2015.
+</p>
+
+<p>
+ Nos marcos de desenvolvimento principais, entregamos atualizações para os dispositivos de teste.
+ Os marcos de experiência são
+</p>
+
+<ul>
+ <li>
+ <strong>Preview&nbsp;1</strong> (lançamento inicial do Preview, final de maio),
+ </li>
+
+ <li>
+ <strong>Preview&nbsp;2</strong> (final de junho/início de julho) e
+ </li>
+
+ <li>
+ <strong>Preview&nbsp;3</strong> (próximo ao final de julho)
+ </li>
+</ul>
+
+<p>
+ Estas atualizações culminam no <strong>SDK final</strong> (no 3º trimestre),
+ que fornecerá APIs oficiais para a nova versão do Android,
+ bem como os recursos e comportamentos do sistema final.
+</p>
+
+<p>
+ Ao testar e desenvolver no Android M, recomendamos que você <strong>mantenha
+ o ambiente de desenvolvimento atualizado</strong> à medida que atualizações do Preview são lançadas.
+ Para facilitar o processo, fornecemos <strong>atualizações "over-the-air"
+ (OTA)</strong> aos dispositivos já programados em flash para uma versão do Preview, além
+ de fornecemos imagens do sistema que estão disponíveis para download e programação em flash manualmente.
+</p>
+<p class="note">
+ <strong>Observação:</strong> as imagens do sistema e o SDK final não podem ser entregues
+ por OTA. Em vez disso, precisarão ser <strong>programadas em flash manualmente</strong> para
+ os dispositivos de teste.</strong>
+</p>
+
+<p>
+ Notificaremos você quando as atualizações do Preview estiverem disponíveis por meio do <a href="http://android-developers.blogspot.com/">Blogue de desenvolvedores do Android</a>, além
+ deste site
+ e da <a href="http://g.co/dev/AndroidMDevPreview">Comunidade Android M Developer</a>.
+</p>
+
+<h2 id="preview_tools">
+ O que há no Preview?
+</h2>
+
+<p>
+ O M Developer Preview inclui tudo que é necessário para testar os aplicativos existentes
+ em uma variedade de tamanhos de tela, tecnologias de rede, chipsets de CPU/GPU
+ e arquiteturas de hardware.
+</p>
+
+<h4>
+ Ferramentas SDK
+</h4>
+
+<p>
+ É possível fazer o download destes componentes pelo SDK Manager no <a href="{@docRoot}sdk/installing/adding-packages.html">Android Studio</a>:
+</p>
+
+<ul>
+ <li>M Developer Preview <strong>ferramentas SDK</strong>
+ </li>
+
+ <li>M Developer Preview <strong>imagem do sistema de emulador</strong> (32 bits
+e 64 bits)
+ </li>
+
+ <li>M Developer Preview <strong>imagem do sistema de emulador para Android TV</strong>
+ (32 bits)
+ </li>
+</ul>
+
+<h4>
+ Imagens do sistema de hardware
+</h4>
+
+<p>
+ É possível fazer o download destas imagens de sistema de hardware para dispositivos Nexus a partir
+ da <a href="download.html">página de download</a>:
+</p>
+
+<ul>
+ <li>
+ <strong>Nexus 5</strong> (GSM/LTE) imagem do sistema de dispositivo “hammerhead”
+ </li>
+
+ <li>
+ <strong>Nexus 6</strong> imagem do sistema de dispositivo “shamu”
+ </li>
+
+ <li>
+ <strong>Nexus 9</strong> (Wi-Fi) imagem do sistema de dispositivo “volantis”
+ </li>
+
+ <li>
+ <strong>Nexus Player</strong> (Android TV) imagem do sistema de dispositivo “fugu”
+ </li>
+</ul>
+
+<h4>
+ Exemplo de código e documentação
+</h4>
+
+<p>
+ Estes recursos de documentação ajudam você a aprender sobre o Preview:
+</p>
+
+<ul>
+ <li>
+ <a href="setup-sdk.html">Configuração do SDK</a> tem instruções passo a passo
+ para você começar.
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/testing/guide.html">Guia de teste</a> e <a href="behavior-changes.html">Mudanças de comportamento</a> mostram as áreas essenciais para o teste.
+ </li>
+
+ <li>Documentação de novas APIs, incluindo uma <a href="api-overview.html">Visão geral das APIs</a>,
+ <a href="{@docRoot}preview/download.html#docs">Referência da API</a> disponível para download e guias de desenvolvedor detalhados sobre
+ os recursos principais, como
+ <a href="{@docRoot}preview/features/runtime-permissions.html">permissões</a>,
+ <a href="{@docRoot}preview/backup/index.html">backup de aplicativo</a> etc.
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/samples.html">Exemplo de código</a> que demonstra como suportar
+ permissões e outros novos recursos.
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/support.html#release-notes">Notas de versão</a> para a versão atual do
+ M Developer Preview, incluindo notas de mudanças e relatórios de diferença.
+ </li>
+</ul>
+
+<h4>
+ Recursos de suporte
+</h4>
+
+<p>
+ Use estes recursos de suporte ao testar e desenvolver no
+ M Developer Preview:
+</p>
+
+<ul>
+ <li>O <a href="https://code.google.com/p/android-developer-preview/">Issue Tracker do M
+ Developer Preview</a> é o <strong>canal principal
+ de feedback.</strong> É possível informar erros, problemas de desempenho e feedback
+ geral pelo issue tracker. Também é possível verificar os <a href="https://code.google.com/p/android-developer-preview/wiki/KnownIssues">erros conhecidos</a>
+ e encontrar etapas de resolução.
+ </li>
+
+ <li>A <a href="http://g.co/dev/AndroidMDevPreview">Comunidade Android M Developer
+</a> é uma comunidade do Google+ onde é possível <strong>se conectar
+ a outros desenvolvedores</strong> que trabalham com o Android M. É possível compartilhar
+ observações ou ideias, além de encontrar respostas para as dúvidas sobre o Android M.
+ </li>
+</ul>
+
+
+<h2 id="preview_apis_and_publishing">
+ Destinação, APIs de prévia e publicação
+</h2>
+
+<p>
+ O Android M Developer Preview é uma versão apenas para desenvolvimento
+ e <strong>não possui um nível da API padrão</strong>. Caso opte
+ pelos comportamentos de compatibilidade para testar o aplicativo (o que é muito recomendado),
+ é possível destinar o M Developer Preview configurando o <code><a href=
+ "/guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a></code>
+ do aplicativo para <code>“MNC”</code>.
+</p>
+
+<p>
+ O Android M Developer Preview fornece <strong>APIs de prévia</strong>
+ &mdash; as APIs não serão oficiais até o lançamento do SDK final,
+ atualmente planejado para o terceiro trimestre de 2015. Isto significa que é possível
+ <strong>esperar alterações secundárias de APIs</strong> com o tempo, especialmente
+ durante as semanas iniciais do programa. Forneceremos um resumo das alterações
+ com cada atualização do Android M Developer Preview.
+</p>
+
+<p class="note">
+ Observe que, apesar das APIs da prévia poderem ser alteradas, os comportamentos essenciais do sistema,
+ como permissões de tempo de execução e recursos de economia de energia, são estáveis e estão prontos
+ para serem testados.
+</p>
+
+<p>
+ Em termos de publicação, o Google Play <strong>evita a publicação de aplicativos
+ destinados para o M Developer Preview</strong>. Quando o SDK final do Android M estiver
+ disponível, você poderá destinar o nível da API do Android M oficial
+ e publicar o aplicativo no Google Play. Enquanto isso, caso queira distribuir um aplicativo
+ destinado para Android M para testadores, é possível fazê-lo por e-mail ou por download direto
+ a partir do site.
+</p>
+
+<h2 id="get_started">
+ Como começar
+</h2>
+
+<p>
+ Para começar o teste do aplicativo:
+</p>
+
+<ol>
+ <li>Revise a <a href="{@docRoot}preview/api-overview.html">Visão geral da API</a>
+ e as <a href="{@docRoot}preview/behavior-changes.html">Mudanças de comportamento</a> para
+ ter uma ideia do que há de novo e como isto afeta os aplicativos. Em particular, aprenda mais sobre
+ o novo modelo<a href="{@docRoot}preview/features/runtime-permissions.html">de permissões
+ de tempo de execução</a>, recursos de economia de energia e backup automático.
+ </li>
+
+ <li>Configure o ambiente seguindo as instruções para
+ <a href="{@docRoot}preview/setup-sdk.html">Configurar o Preview SDK</a>
+ e ajustar os dispositivos de teste.
+ </li>
+
+ <li>Siga <a href="https://developers.google.com/android/nexus/images">
+ as instruções de programação em flash</a> para programar em flash a imagem do sistema do M Developer Preview mais recente
+ para Nexus 5, 6, 9 e Player. Após programar em flash o dispositivo de desenvolvimento,
+ as atualizações do Preview serão entregues por atualizações OTA (over-the-air).</a>
+ </li>
+
+ <li>Faça o download da <a href="{@docRoot}preview/download.html#docs">Referência da API do
+ M Preview</a> e dos <a href="{@docRoot}preview/samples.html">exemplos do M Preview
+</a> para obter mais informações sobre os novos recursos de API e como usá-los
+ no aplicativo.
+ </li>
+
+ <li>Junte-se à <a href="http://g.co/dev/AndroidMDevPreview">Comunidade Android M
+ Developer</a> para obter as notícias mais recentes e conecte-se a outros
+ desenvolvedores que trabalham com a nova plataforma.
+ </li>
+</ol>
+
+<p>
+ Agradecemos a sua participação no programa M Developer Preview do Android!
+</p>
diff --git a/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/index.jd b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/index.jd
new file mode 100644
index 0000000..5912058
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/index.jd
@@ -0,0 +1,72 @@
+page.title=Como gerenciar o ciclo de vida da atividade
+page.tags=ciclo de vida da atividade
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+
+<h2>Dependências e pré-requisitos</h2>
+<ul>
+ <li>Como criar um projeto do Android (consulte <a href="{@docRoot}training/basics/firstapp/creating-project.html">Como criar um projeto
+do Android</a>)</li>
+</ul>
+
+
+<h2>Leia também</h2>
+<ul>
+ <li><a href="{@docRoot}guide/components/activities.html">Atividades</a></li>
+</ul>
+
+
+<h2>Tente</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">Baixar a demonstração</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>Conforme o usuário navega, sai e retorna para o seu aplicativo, as
+instâncias {@link android.app.Activity} no aplicativo transitam entre diferentes estados no
+ciclo de vida. Por exemplo, quando a
+atividade começa pela primeira vez, ela fica em primeiro plano no sistema e tem o foco do
+usuário. Durante o processo, o sistema Android chama uma série de métodos do ciclo de vida na
+atividade, onde você define a interface do usuário e outros componentes. Se o usuário executa uma
+ação que inicia outra atividade ou alterna para outro aplicativo, o sistema chama outro conjunto de
+métodos do ciclo de vida em sua atividade conforme ela fica em segundo plano (onde a atividade já não
+está visível, mas a instância e seu estado permanecem intactos).</p>
+
+<p>Dentro dos métodos de retorno de chamada do ciclo de vida, você pode declarar como a atividade deve se comportar quando o
+usuário sai e retorna da atividade. Por exemplo, se estiver construindo um reprodutor de vídeos de transmissão em sequência,
+você pode pausar o vídeo e encerrar a conexão da rede quando o usuário alternar para outro
+aplicativo. Quando o usuário retornar, será possível reconectar a rede e permitir que ele reinicie o vídeo
+de onde parou.</p>
+
+<p>Essa lição explica a importância dos métodos de retorno de chamada do ciclo de vida que cada instância {@link
+android.app.Activity} recebe e como utilizá-los para que a atividade faça o que o
+usuário espera e não consuma recursos do sistema quando não estiver em uso.</p>
+
+<h2>Lições</h2>
+
+<dl>
+ <dt><b><a href="starting.html">Iniciando uma atividade</a></b></dt>
+ <dd>Aprenda os fundamentos sobre ciclo de vida da atividade, como o usuário pode iniciar seu aplicativo e como
+executar atividades básicas de criação.</dd>
+ <dt><b><a href="pausing.html">Pausando e reiniciando uma atividade</a></b></dt>
+ <dd>Aprenda sobre o que acontece quando sua atividade é pausada (parcialmente obscurecida) e retomada e o que
+fazer durante essas mudanças de estados.</dd>
+ <dt><b><a href="stopping.html">Interrompendo e reiniciando uma atividade</a></b></dt>
+ <dd>Aprenda sobre o que acontece quando o usuário sai da atividade completamente e retorna.</dd>
+ <dt><b><a href="recreating.html">Recriando uma atividade</a></b></dt>
+ <dd>Aprenda sobre o que acontece quando sua atividade é destruída e como reconstruir o estado
+da atividade quando necessário.</dd>
+</dl>
+
diff --git a/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/pausing.jd b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/pausing.jd
new file mode 100644
index 0000000..55f772e
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/pausing.jd
@@ -0,0 +1,147 @@
+page.title=Pausando e reiniciando uma atividade
+page.tags=ciclo de vida da atividade
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>Esta lição ensina a</h2>
+ <ol>
+ <li><a href="#Pause">Pausar sua atividade</a></li>
+ <li><a href="#Resume">Reiniciar sua atividade</a></li>
+ </ol>
+
+ <h2>Leia também</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">Atividades</a>
+ </li>
+ </ul>
+
+<h2>Tente</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">Baixar a demonstração</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>Durante o uso normal do aplicativo, a atividade em primeiro plano as vezes é obstruída por outros
+componentes visuais que causam a <em>pausa</em>. Por exemplo, quando uma atividade
+ semitransparente é aberta (como uma no estilo de um diálogo), a atividade anterior pausa. Enquanto a
+atividade estiver parcialmente visível, mas não for o foco da atividade, ela permanecerá pausada.</p>
+
+<p>No entanto, se a atividade estiver completamente obstruída e não visível, ela <em>para</em> (o que será
+discutido na próxima lição).</p>
+
+<p>Conforme a atividade entra no estado pausado, o sistema chama o método {@link
+android.app.Activity#onPause onPause()} em seu {@link android.app.Activity}, que permite
+interromper ações em andamento que não devem continuar enquanto pausadas (como um vídeo) nem persistir
+quaisquer informações que devam ser permanentemente salvas caso o usuário continue a sair do aplicativo. Se
+o usuário retornar à atividade do estado de pausa, o sistema a reiniciará e chamará o método
+{@link android.app.Activity#onResume onResume()}.</p>
+
+<p class="note"><strong>Observação:</strong> quando a atividade receber o chamado para {@link
+android.app.Activity#onPause()}, pode ser um indicativo de que a atividade será pausada por um
+momento e o usuário poderá retornar o foco para a atividade. No entanto, geralmente é um indicativo
+de que o usuário está saindo da atividade.</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-paused.png" />
+<p class="img-caption"><strong>Figura 1.</strong> Quando uma atividade semitransparente obscurece
+sua atividade, o sistema chama {@link android.app.Activity#onPause onPause()} e a atividade
+aguarda no estado Pausa (1). Se o usuário retornar à atividade enquanto ainda estiver pausada, o
+ sistema chama {@link android.app.Activity#onResume onResume()} (2).</p>
+
+
+<h2 id="Pause">Pausar sua atividade</h2>
+
+<p>Quando o sistema chama {@link android.app.Activity#onPause()} para sua atividade, teoricamente
+significa que a atividade ainda está parcialmente visível, mas geralmente é um indício
+de que o usuário está saindo da atividade e logo entrará em estado Interrompido. Use
+o retorno de chamada {@link android.app.Activity#onPause()} para:</p>
+
+<ul>
+ <li>Interromper animações ou outras ações em andamento que consomem a CPU.</li>
+ <li>Consolidar alterações não salvas apenas se o usuário esperar que essas alterações sejam permanentemente salvas ao
+saírem (como um rascunho de email).</li>
+ <li>Liberar recursos do sistema, como receptores, cabos para sensores (como
+GPS), ou outros recursos que podem afetar a vida da bateria enquanto a atividade estiver pausada e o usuário
+não precisar deles.</li>
+</ul>
+
+<p>Por exemplo, se seu aplicativo utiliza o {@link android.hardware.Camera}, o método
+{@link android.app.Activity#onPause()} é um bom local para liberá-los.</p>
+
+<pre>
+&#64;Override
+public void onPause() {
+ super.onPause(); // Always call the superclass method first
+
+ // Release the Camera because we don't need it when paused
+ // and other activities might need to use it.
+ if (mCamera != null) {
+ mCamera.release()
+ mCamera = null;
+ }
+}
+</pre>
+
+<p>Geralmente, recomenda-se <strong>não</strong> utilizar {@link android.app.Activity#onPause()} para armazenar
+alterações do usuário (como informações pessoais digitadas em um formulário) para armazenamento permanente. O único momento
+que se deve persistir na mudança do usuário para armazenamento permanente dentro do {@link android.app.Activity#onPause()}
+é quando tem certeza de que o usuário espera que as alterações sejam salvas automaticamente (como ao esboçar um email).
+No entanto, evite executar trabalhos de uso intensivo da CPU durante {@link
+android.app.Activity#onPause()}, como gravar em um banco de dados, porque isso pode retardar a transição
+visível para a próxima atividade (execute operações de encerramento pesadas durante
+{@link android.app.Activity#onStop onStop()}).</p>
+
+<p>Simplifique a quantidade de operações feitas no método {@link android.app.Activity#onPause
+onPause()} para permitir uma transição mais rápida para o próximo
+destino do usuário se a atividade for realmente interrompida.</p>
+
+<p class="note"><strong>Observação:</strong> quando a atividade está pausada, a instância {@link
+android.app.Activity} é mantida na memória e chamada novamente quando a atividade é retomada.
+Não é necessário reiniciar componentes que foram criados durante qualquer método de retorno de chamada que
+leve ao estado Reiniciado.</p>
+
+
+
+<h2 id="Resume">Reiniciar sua atividade</h2>
+
+<p>Quando o usuário reinicia a atividade do estado Pausado, o sistema chama o método {@link
+android.app.Activity#onResume()}.</p>
+
+<p>Certifique-se de que o sistema chama esse método sempre que a atividade entrar no primeiro plano,
+mesmo quando estiver sendo criada. Dessa forma, implemente o {@link
+android.app.Activity#onResume()} para inicializar os componentes liberados durante {@link
+android.app.Activity#onPause()} e execute quaisquer outras inicializações que devem ocorrer sempre que a
+atividade entrar em estado Reiniciado (como ao iniciar animações e componentes de inicialização usados apenas
+enquanto a atividade tiver o foco do usuário).</p>
+
+<p>O seguinte exemplo de {@link android.app.Activity#onResume()} é uma contrapartida ao
+exemplo {@link android.app.Activity#onPause()} acima. Portanto, ele inicializa a câmera que é
+ liberada quando a atividade entra em pausa.</p>
+
+<pre>
+&#64;Override
+public void onResume() {
+ super.onResume(); // Always call the superclass method first
+
+ // Get the Camera instance as the activity achieves full user focus
+ if (mCamera == null) {
+ initializeCamera(); // Local method to handle camera init
+ }
+}
+</pre>
+
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/recreating.jd b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/recreating.jd
new file mode 100644
index 0000000..7cb122f
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/recreating.jd
@@ -0,0 +1,178 @@
+page.title=Recriando uma atividade
+page.tags=ciclo de vida da atividade
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>Esta lição ensina a</h2>
+ <ol>
+ <li><a href="#SaveState">Salvar o estado da atividade</a></li>
+ <li><a href="#RestoreState">Restaurar o estado da atividade</a></li>
+ </ol>
+
+ <h2>Leia também</h2>
+ <ul>
+ <li><a href="{@docRoot}training/basics/supporting-devices/screens.html">Compatibilidade
+ com diferentes telas</a></li>
+ <li><a href="{@docRoot}guide/topics/resources/runtime-changes.html">Tratar alterações no tempo de execução</a></li>
+ <li><a href="{@docRoot}guide/components/activities.html">Atividades</a>
+ </li>
+ </ul>
+
+ </div>
+</div>
+
+<p>Estas são algumas possibilidade onde a atividade é destruída devido ao comportamento normal do aplicativo, como
+quando o usuário pressiona o botão <em>Voltar</em> ou sua atividade sinaliza sua própria destruição
+chamando {@link android.app.Activity#finish()}. O sistema também pode destruir a atividade se
+for interrompida e não tiver sido utilizada por um longo período de tempo ou a atividade do primeiro plano exigir mais
+recursos, então, o sistema deverá fechar processos de segundo plano para recuperar memória.</p>
+
+<p>Quando a atividade é destruída porque o usuário pressiona <em>Voltar</em> ou a atividade se
+encerra, o conceito do sistema de que a instância {@link android.app.Activity} se perde
+porque o comportamento indica que a atividade já não é necessária. No entanto, se o sistema destruir
+a atividade devido a limitações do sistema (em vez do comportamento normal do aplicativo), embora a instância real
+{@link android.app.Activity} tenha se perdido, o sistema lembra que ela existiu de forma que se
+o usuário navegar de volta, o sistema criará uma nova instância da atividade usando um conjunto
+de dados salvos que descrevem o estado da atividade quando foi destruída. Os dados salvos
+utilizados pelo sistema para restaurar o estado anterior é chamado de “estado da instância” e é uma coleção
+de pares de valores-chave armazenados no objeto {@link android.os.Bundle}.</p>
+
+<p class="caution"><strong>Cuidado:</strong> a atividade é destruída e recriada cada vez
+que o usuário girar a tela. Quando a tela altera a orientação, o sistema destrói e recria
+a atividade de primeiro plano porque a configuração da tela mudou e a atividade talvez precise
+carregar recursos alternativos (como o layout).</p>
+
+<p>Por padrão, o sistema usa o estado da instância {@link android.os.Bundle} para salvar informações
+sobre cada objeto {@link android.view.View} em seu layout de atividade (como o valor do texto informado
+em um objeto {@link android.widget.EditText}). Assim, se a instância da atividade for destruída e
+recriada, o estado do layout é restaurado em seu estado anterior sem
+que haja necessidade de códigos. No entanto, sua
+atividade pode conter mais informações de estado do que se deseja restaurar, como varáveis de membro que
+rastreiam o progresso do usuário na atividade.</p>
+
+<p class="note"><strong>Observação:</strong> para que o sistema Android restaure o estado das
+visualizações em sua atividade, <strong>cada visualização precisa ter uma ID exclusiva</strong>, fornecido pelo atributo
+<a href="{@docRoot}reference/android/view/View.html#attr_android:id">{@code
+android:id}</a>.</p>
+
+<p>Para salvar dados adicionais sobre o estado da atividade, substitua
+o método de retorno de chamada {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}.
+O sistema chama este método quando o usuário sai da atividade
+e transmite o objeto{@link android.os.Bundle}, que será salvo
+caso a atividade seja destruída inesperadamente. Se
+o sistema precisar recriar a instância da atividade posteriormente, transmitirá o mesmo objeto {@link
+android.os.Bundle} para ambos os métodos {@link android.app.Activity#onRestoreInstanceState
+onRestoreInstanceState()} e {@link android.app.Activity#onCreate onCreate()}
+.</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-savestate.png" />
+<p class="img-caption"><strong>Figura 2.</strong> Conforme o sistema começa a interromper a atividade, ele
+chama {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}(1) para que você possa especificar
+outros dados de estado que gostaria de salvar caso a instância {@link android.app.Activity} precise ser
+recriada.
+Se a atividade for destruída e a mesma instância precisar ser recriada, o sistema transmite os dados do
+estado definidos em (1) para ambos os métodos {@link android.app.Activity#onCreate onCreate()}
+(2) e {@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}
+(3).</p>
+
+
+
+<h2 id="SaveState">Salvar o estado da atividade</h2>
+
+<p>Conforme a atividade é interrompida, o sistema chama {@link android.app.Activity#onSaveInstanceState
+onSaveInstanceState()} para que a atividade possa salvar informações de estado com uma coleção de pares de
+valor-chave. A implementação padrão deste método salva informações sobre o estado da hierarquia de exibições
+da atividade, como o texto em um widget {@link android.widget.EditText} ou a posição de rolagem
+de um {@link android.widget.ListView}.</p>
+
+<p>Para salvar informações de estado adicionais para a atividade,
+implemente {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} e adicione
+pares de valor-chave ao objeto {@link android.os.Bundle}. Por exemplo:</p>
+
+<pre>
+static final String STATE_SCORE = "playerScore";
+static final String STATE_LEVEL = "playerLevel";
+...
+
+&#64;Override
+public void onSaveInstanceState(Bundle savedInstanceState) {
+ // Save the user's current game state
+ savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
+ savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
+
+ // Always call the superclass so it can save the view hierarchy state
+ super.onSaveInstanceState(savedInstanceState);
+}
+</pre>
+
+<p class="caution"><strong>Cuidado:</strong> sempre chame a implementação de superclasse de {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()} para que a implementação padrão
+possa salvar o estado da hierarquia de exibições.</p>
+
+
+
+<h2 id="RestoreState">Restaurar o estado da atividade</h2>
+
+<p>Quando a atividade é recriada depois de ter sido destruída, é possível recuperar o estado
+salvo do {@link android.os.Bundle} que o sistema
+transmitiu a atividade. Ambos os métodos de retorno de chamada {@link android.app.Activity#onCreate onCreate()} e {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} recebem
+o mesmo {@link android.os.Bundle} que contém informações do estado da instância.</p>
+
+<p>Como o método {@link android.app.Activity#onCreate onCreate()} é chamado se o
+sistema estiver criando uma nova instância da atividade ou recriando uma anterior, verifique
+se o {@link android.os.Bundle} do estado é null antes de tentar realizar a leitura. Se for null,
+o sistema estará criando uma nova instância da atividade em vez de restaurar uma anterior
+que tenha sido destruída.</p>
+
+<p>Por exemplo, esta é uma forma de restaurar alguns dados de estado no {@link android.app.Activity#onCreate
+onCreate()}:</p>
+
+<pre>
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState); // Always call the superclass first
+
+ // Check whether we're recreating a previously destroyed instance
+ if (savedInstanceState != null) {
+ // Restore value of members from saved state
+ mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
+ mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
+ } else {
+ // Probably initialize members with default values for a new instance
+ }
+ ...
+}
+</pre>
+
+<p>Em vez de restaurar o estado durante {@link android.app.Activity#onCreate onCreate()}, você
+pode implementar {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}, que o sistema chama
+depois do método {@link android.app.Activity#onStart()}. O sistema chama {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} se houver um estado
+salvo para ser restaurado. Portanto, não é necessário verificar se {@link android.os.Bundle} é null:</p>
+
+<pre>
+public void onRestoreInstanceState(Bundle savedInstanceState) {
+ // Always call the superclass so it can restore the view hierarchy
+ super.onRestoreInstanceState(savedInstanceState);
+
+ // Restore state members from saved instance
+ mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
+ mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
+}
+</pre>
+
+<p class="caution"><strong>Cuidado:</strong> sempre chame a implementação de superclasse de {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} para que a implementação padrão
+possa restaurar o estado da hierarquia de exibições.</p>
+
+<p>Para saber mais sobre recriação de atividades devido a
+um evento de reinicialização no tempo de execução (como quando a tela gira), consulte <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Tratar alterações no tempo de execução</a>.</p>
+
diff --git a/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/starting.jd b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/starting.jd
new file mode 100644
index 0000000..1f8f080
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/starting.jd
@@ -0,0 +1,285 @@
+page.title=Iniciando uma atividade
+page.tags=ciclo de vida de atividade
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>Esta lição ensina a</h2>
+<ol>
+ <li><a href="#lifecycle-states">Entender o ciclo de vida do retorno de chamada</a></li>
+ <li><a href="#launching-activity">Especificar a atividade da tela de início do aplicativo</a></li>
+ <li><a href="#Create">Criar uma nova instância</a></li>
+ <li><a href="#Destroy">Destruir a atividade</a></li>
+</ol>
+
+ <h2>Leia também</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">Atividades</a></li>
+ </ul>
+
+<h2>Tente</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">Baixar a demonstração</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>Diferente de outros paradigmas de programação em que os aplicativos são lançados com um método {@code main()}, o
+sistema Android inicia o código em uma instância {@link android.app.Activity} chamando métodos específicos
+de retorno de chamada que correspondem a determinados estágios do seu
+ciclo de vida. Há uma sequência de métodos de retorno de chamada que iniciam uma atividade e uma sequência de métodos
+de retorno de chamada que interrompem uma atividade.</p>
+
+<p>Essa lição proporciona uma visão geral dos métodos do ciclo de vida mais importantes e mostra como
+lidar com o primeiro retorno de chamada do ciclo de vida que cria uma nova instância de sua atividade.</p>
+
+
+
+<h2 id="lifecycle-states">Entender o ciclo de vida do retorno de chamada</h2>
+
+<p>Durante a vida de uma atividade, o sistema chama um núcleo principal de métodos do ciclo de vida em
+uma sequência parecida com uma pirâmide em degraus. Isto é, cada estágio do
+ciclo de vida da atividade corresponde a um degrau da pirâmide. Conforme o sistema cria uma nova instância de atividade,
+cada método de retorno de chamada leva o estado da atividade um degrau acima. O topo da pirâmide é o
+ponto em que a atividade funciona em primeiro plano e o usuário pode interagir com ela.</p>
+
+<p>Conforme o usuário começa a sair da atividade, o sistema chama outros métodos que a movem
+de volta em direção à base da pirâmide para desfazer a atividade. Em alguns casos, a atividade é movida
+parcialmente em direção à base da pirâmide e aguarda (como quando o usuário muda para outro aplicativo), no
+ponto em que a atividade é movida novamente em direção ao topo (se o usuário retornar à atividade) e
+reinicia de onde o usuário parou.</p>
+
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle.png" />
+<p class="img-caption"><strong>Figura 1.</strong> Ilustração simplificada do ciclo de vida
+da atividade, expressa como pirâmide em degraus. Isso mostra que, para cada retorno de chamada usado para levar
+uma atividade ao estado de Reiniciado, em direção ao topo, há um método de retorno de chamada
+que leva a atividade um degrau abaixo. A atividade também pode retornar ao estado de retomada do
+estado de Pausado e Interrompido.</p>
+
+
+<p>Dependendo da complexidade de sua atividade, não há necessidade de implementar todos os
+métodos do ciclo de vida. No entanto, é importante compreender cada um e implementar apenas aqueles que
+garantem que seu aplicativo tenha o desempenho esperado pelo usuário. A implementação adequada dos métodos do ciclo de vida da atividade
+garante que seu aplicativo tenha um bom desempenho em vários sentidos, incluindo que:</p>
+<ul>
+ <li>Não apresente falhas se o usuário receber uma chamada telefônica ou mudar para outro aplicativo
+enquanto estiver usando o seu aplicativo.</li>
+ <li>Não consuma recursos importantes do sistema quando o usuário não estiver utilizando
+ativamente o aplicativo.</li>
+ <li>Não perca o progresso do usuário se ele sair do aplicativo e retornar
+mais tarde.</li>
+ <li>Não apresente falhas nem perca o progresso do usuário quando a orientação da tela mudar entre
+paisagem e retrato.</li>
+</ul>
+
+<!--
+<p class="table-caption"><strong>Table 1.</strong> Activity lifecycle state pairs and callback
+methods.</p>
+<table>
+ <tr>
+ <th scope="col">Lifecycle State</th>
+ <th scope="col">Startup Method</th>
+ <th scope="col">Teardown Method</th>
+ </tr>
+ <tr>
+ <td>Created / Destroyed</td>
+ <td>{@link android.app.Activity#onCreate onCreate()}</td>
+ <td>{@link android.app.Activity#onDestroy()}</td>
+ </tr>
+ <tr>
+ <td>Started / Stopped</td>
+ <td>{@link android.app.Activity#onStart()}</td>
+ <td>{@link android.app.Activity#onStop()}</td>
+ </tr>
+ <tr>
+ <td>Resumed / Resumed</td>
+ <td>{@link android.app.Activity#onResume()}</td>
+ <td>{@link android.app.Activity#onPause()}</td>
+ </tr>
+</table>
+-->
+
+<p>Como você aprenderá nas lições seguintes, há várias situações de transições de
+atividades entre estados diferentes, como ilustrado na figura 1. No entanto, apenas três
+desses estados podem ser estáticos. Isto é, a atividade pode existir em um de apenas três estados por
+um período de tempo maior:</p>
+<dl>
+ <dt>Reiniciado</dt>
+ <dd>Neste estado, a atividade está no primeiro plano e o usuário consegue interagir.
+(Também chamado de estado de funcionamento.)</dd>
+ <dt>Pausado</dt>
+ <dd>Neste estado, a atividade está parcialmente obscurecida por outra atividade. A
+outra atividade que está em primeiro plano é semitransparente ou não cobre totalmente a tela. A
+atividade pausada não recebe entrada do usuário e não executa nenhum código.
+ <dt>Interrompido</dt>
+ <dd>Neste estado, a atividade está completamente oculta e não é visível para o usuário. Considera-se
+que está em segundo plano. Enquanto interrompido, a instância da atividade e todas as
+informações de estado, como variáveis de membro, são retidas, mas não é possível executar nenhum código.</dd>
+</dl>
+
+<p>Os outros estados (Criado e Iniciado) são temporários e o sistema rapidamente se move rapidamente de um
+estado a outro chamando o próximo método de retorno de chamada do ciclo de vida. Isto é, depois que o sistema chama
+{@link android.app.Activity#onCreate onCreate()}, ele rapidamente chama {@link
+android.app.Activity#onStart()}, que é seguido por {@link
+android.app.Activity#onResume()}.</p>
+
+<p>Isso é tudo que precisamos dizer sobre o ciclo de vida básico de atividades. Agora você aprenderá sobre alguns dos
+comportamentos específicos do ciclo de vida.</p>
+
+
+
+<h2 id="launching-activity">Especificar a atividade da tela de início do aplicativo</h2>
+
+<p>Quando o usuário seleciona seu aplicativo na tela inicial, o sistema chama o método {@link
+android.app.Activity#onCreate onCreate()} para {@link android.app.Activity} no aplicativo
+que foi declarado como atividade da “inicializador” (ou “principal”). Essa é a atividade que serve como
+ponto de entrada principal da interface do usuário do aplicativo.</p>
+
+<p>É possível definir qual atividade será usada como principal no arquivo manifesto do Android, <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">{@code AndroidManifest.xml}</a>, que está
+na raiz do diretório do seu projeto.</p>
+
+<p>A principal atividade do aplicativo deve ser declarada no manifesto com um <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a> que inclui a ação {@link
+android.content.Intent#ACTION_MAIN MAIN} e categoria
+{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER}. Por exemplo:</p>
+
+<pre>
+&lt;activity android:name=".MainActivity" android:label="&#64;string/app_name">
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.MAIN" />
+ &lt;category android:name="android.intent.category.LAUNCHER" />
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p class="note"><strong>Observação:</strong> ao criar um novo projeto do Android com ferramentas
+SDK Android, os arquivos padrões do projeto incluem uma classe {@link android.app.Activity} que é declarada no
+manifesto com esse filtro.</p>
+
+<p>Se a ação {@link android.content.Intent#ACTION_MAIN MAIN} nem a categoria
+{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} forem declaradas para uma de suas
+atividades, o ícone do aplicativo não aparecerá na lista de aplicativos da tela inicial.</p>
+
+
+
+<h2 id="Create">Criar uma nova instância</h2>
+
+<p>A maioria dos aplicativos tem várias atividades que permitem ao usuário realizar diferentes ações.
+Tanto para a atividade principal criada quando o usuário clica no ícone do aplicativo quanto uma
+atividade diferente que o aplicativo inicia em resposta à ação do usuário, o sistema cria
+cada nova instância do {@link android.app.Activity} chamando o método {@link
+android.app.Activity#onCreate onCreate()}.</p>
+
+<p>Implemente o método {@link android.app.Activity#onCreate onCreate()} para realizar a lógica básica
+de inicialização do aplicativo que deve acontecer apenas uma vez na vida completa da atividade. Por
+exemplo, sua implementação do {@link android.app.Activity#onCreate onCreate()} deve definir a
+interface do usuário e possivelmente instanciar algumas variáveis de escopo de classe.</p>
+
+<p>Por exemplo, o seguinte modelo do método {@link android.app.Activity#onCreate onCreate()}
+ mostra alguns códigos que realizam configurações fundamentais para a atividade, como
+declarar a interface do usuário (definida em arquivo de layout XML), definir variáveis de membro
+e configurar parte da interface do usuário.</p>
+
+<pre>
+TextView mTextView; // Member variable for text view in the layout
+
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Set the user interface layout for this Activity
+ // The layout file is defined in the project res/layout/main_activity.xml file
+ setContentView(R.layout.main_activity);
+
+ // Initialize member TextView so we can manipulate it later
+ mTextView = (TextView) findViewById(R.id.text_message);
+
+ // Make sure we're running on Honeycomb or higher to use ActionBar APIs
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ // For the main activity, make sure the app icon in the action bar
+ // does not behave as a button
+ ActionBar actionBar = getActionBar();
+ actionBar.setHomeButtonEnabled(false);
+ }
+}
+</pre>
+
+<p class="caution"><strong>Cuidado:</strong> utilizar {@link android.os.Build.VERSION#SDK_INT} para
+evitar que sistemas antigos executem novas APIs funciona apenas no Android 2.0 (API Nível
+5) e versões posteriores. Versões mais antigas encontram uma exceção no tempo de execução.</p>
+
+<p>Depois que o {@link android.app.Activity#onCreate onCreate()} termina de executar, o sistema
+chama os métodos {@link android.app.Activity#onStart()} e {@link android.app.Activity#onResume()}
+ em rápida sucessão. A atividade nunca reside nos estados Criado ou Iniciado. Tecnicamente, a
+atividade se torna visível para o usuário quando {@link android.app.Activity#onStart()} é chamado, mas
+{@link android.app.Activity#onResume()} é executado e a atividade permanece no estado Reiniciado
+até que algo diferente ocorra, como o recebimento de uma chamada telefônica, o usuário
+navegar para outra atividade ou a tela do dispositivo desligar.</p>
+
+<p>Nas próximas lições, você verá como outros métodos de inicialização, {@link
+android.app.Activity#onStart()} e {@link android.app.Activity#onResume()}, podem ajudar
+no ciclo de vida da atividade quando utilizado para reiniciar a atividade dos estados Pausado e Interrompido.</p>
+
+<p class="note"><strong>Observação:</strong> o método {@link android.app.Activity#onCreate onCreate()}
+inclui um parâmetro chamado <code>savedInstanceState</code>, que será discutido mais adiante
+na lição <a href="recreating.html">Recriando uma atividade</a>.</p>
+
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-create.png" />
+<p class="img-caption"><strong>Figura 2.</strong> Outra ilustração da estrutura do ciclo de vida da
+atividade com ênfase nos três retornos de chamada principais que o sistema chama na sequência quando
+cria uma nova instância da atividade: {@link android.app.Activity#onCreate onCreate()}, {@link
+android.app.Activity#onStart()} e{@link android.app.Activity#onResume()}. Depois que esta sequência de
+retornos de chamada for concluída, a atividade chega ao estado Reiniciado em que os usuários podem interagir com a
+atividade até que mude para outra atividade.</p>
+
+
+
+
+
+
+
+<h2 id="Destroy">Destruir a atividade</h2>
+
+<p>Embora o retorno de chamada do primeiro ciclo de vida da atividade seja {@link android.app.Activity#onCreate
+onCreate()}, o último retorno de chamada será {@link android.app.Activity#onDestroy}. O sistema chama
+este método na atividade como o último
+sinal de que a instância da atividade está sendo completamente removida da memória do sistema.</p>
+
+<p>A maioria dos aplicativos não exige a implementação desse método porque referências de classe locais são destruídas
+com a atividade, que realiza a maior parte da limpeza durante {@link
+android.app.Activity#onPause} e {@link android.app.Activity#onStop}. No entanto, se a
+atividade incluir threads de segundo plano criados durante {@link
+android.app.Activity#onCreate onCreate()} ou outro recurso de longa execução que pode
+vazar memória se não forem fechados adequadamente, você deve finalizá-los durante {@link
+android.app.Activity#onDestroy}.</p>
+
+<pre>
+&#64;Override
+public void onDestroy() {
+ super.onDestroy(); // Always call the superclass
+
+ // Stop method tracing that the activity started during onCreate()
+ android.os.Debug.stopMethodTracing();
+}
+</pre>
+
+<p class="note"><strong>Observação:</strong> o sistema chama {@link android.app.Activity#onDestroy}
+depois de ter chamado {@link android.app.Activity#onPause} e {@link
+android.app.Activity#onStop} em qualquer situação, exceto uma: quando você chama {@link
+android.app.Activity#finish()} pelo método {@link android.app.Activity#onCreate onCreate()}
+. Em alguns casos, como quando a atividade assume a posição temporária de tomadora de decisões para
+lançar outra atividade, chame {@link android.app.Activity#finish()} pelo {@link
+android.app.Activity#onCreate onCreate()} para destruir a atividade. Nesse caso, o sistema
+chama imediatamente {@link android.app.Activity#onDestroy} sem chamar qualquer outro
+ método do ciclo de vida.</p>
diff --git a/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/stopping.jd b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/stopping.jd
new file mode 100644
index 0000000..2eba377
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/stopping.jd
@@ -0,0 +1,187 @@
+page.title=Interrompendo e reiniciando uma atividade
+page.tags=ciclo de vida da atividade
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>Esta lição ensina a</h2>
+ <ol>
+ <li><a href="#Stop">Interromper sua atividade</a></li>
+ <li><a href="#Start">Iniciar/reiniciar sua atividade</a></li>
+ </ol>
+
+ <h2>Leia também</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">Atividades</a>
+ </li>
+ </ul>
+
+<h2>Tente</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">Baixar a demonstração</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>Interromper e reiniciar adequadamente sua atividade é um processo importante no ciclo de vida da atividade
+que garante que o usuário perceba que o aplicativo está sempre ativo e não perca o progresso.
+Há alguns cenários fundamentais em que sua atividade é interrompida e reiniciada:</p>
+
+<ul>
+ <li>O usuário abre a janela Aplicativos Utilizados Recentemente e alterna de um aplicativo a outro. A
+atividade em seu aplicativo atualmente em primeiro plano é interrompida. Se o usuário retornar ao
+aplicativo pelo ícone de inicialização da tela inicial ou da janela Aplicativos Utilizados Recentemente, a atividade é reiniciada.</li>
+ <li>O usuário executar uma ação em seu aplicativo que inicia uma nova atividade. A atividade atual
+é interrompida quando a segunda é criada. Se o usuário pressionar o botão <em>Voltar</em>
+, a primeira atividade será reiniciada.</li>
+ <li>Se o usuário receber uma chamada telefônica enquanto estiver usando o seu aplicativo.</li>
+</ul>
+
+<p>A classe {@link android.app.Activity} fornece dois métodos do ciclo de vida, {@link
+android.app.Activity#onStop()} e {@link android.app.Activity#onRestart()}, que permite que você
+decida exatamente como a atividade responderá à interrupção e reinicialização. Diferentemente do estado pausado,
+que identifica obstruções parciais da interface de usuário, o estado interrompido garante que a interface não fique
+visível e que o foco do usuário permaneça em outra atividade (ou mesmo outro aplicativo).</p>
+
+<p class="note"><strong>Observação:</strong> como o sistema retém a instância {@link android.app.Activity}
+na memória quando interrompida, talvez não seja necessário implementar os métodos
+{@link android.app.Activity#onStop()} e {@link android.app.Activity#onRestart()} (ou mesmo {@link
+android.app.Activity#onStart()}. Para a maioria das atividades que são relativamente simples, a
+atividade será interrompida e reiniciada normalmente e talvez seja necessário apenas usar {@link
+android.app.Activity#onPause()} para pausar ações em andamento e desconectar dos recursos do sistema.</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-stopped.png" />
+<p class="img-caption"><strong>Figura 1.</strong> Quando o usuário sai da atividade, o sistema
+chama {@link android.app.Activity#onStop onStop()} para interrompê-la (1). Se o usuário retornar
+enquanto a atividade estiver interrompida, o sistema chama {@link android.app.Activity#onRestart onRestart()}
+(2), rapidamente seguido por {@link android.app.Activity#onStart onStart()} (3) e {@link
+android.app.Activity#onResume()} (4). Observe que independentemente do que tenha causado a interrupção
+da atividade, o sistema sempre chama {@link android.app.Activity#onPause onPause()} antes de chamar {@link
+android.app.Activity#onStop onStop()}.</p>
+
+
+
+<h2 id="Stop">Interromper sua atividade</h2>
+
+<p>Quando sua atividade recebe uma chamada para o método {@link android.app.Activity#onStop()}, não
+está mais visível e deve liberar quase todos os recursos que não foram necessários enquanto o usuário não
+estiver utilizando. Quando a atividade for interrompida, o sistema pode destruir a instância se for necessário para
+recuperar memória do sistema. Em casos extremos, o sistema pode simplesmente desligar o processo do aplicativo sem
+chamar o retorno de chamada{@link android.app.Activity#onDestroy()} final da atividade, portanto, é importante
+usar {@link android.app.Activity#onStop()} para liberar recursos que podem vazar memória.</p>
+
+<p>Embora o método {@link android.app.Activity#onPause onPause()} seja chamado antes de
+{@link android.app.Activity#onStop()}, use {@link android.app.Activity#onStop onStop()}
+para executar operações de desligamento maiores, que exigem mais da CPU, como escrever informação no
+banco de dados.</p>
+
+<p>Por exemplo, esta é uma implementação de {@link android.app.Activity#onStop onStop()} que
+salva os conteúdos de uma nota de rascunho no armazenamento persistente:</p>
+
+<!-- TODO: Find a better example for onStop, because this kind of thing should probably use a
+separate thread but that's too complicated to show here. -->
+<pre>
+&#64;Override
+protected void onStop() {
+ super.onStop(); // Always call the superclass method first
+
+ // Save the note's current draft, because the activity is stopping
+ // and we want to be sure the current note progress isn't lost.
+ ContentValues values = new ContentValues();
+ values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
+ values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());
+
+ getContentResolver().update(
+ mUri, // The URI for the note to update.
+ values, // The map of column names and new values to apply to them.
+ null, // No SELECT criteria are used.
+ null // No WHERE columns are used.
+ );
+}
+</pre>
+
+<p>Quando sua atividade é interrompida, o objeto {@link android.app.Activity} é mantido na memória
+e é chamado novamente quando a atividade é reiniciada. Não é necessário reiniciar componentes que foram
+criados durante qualquer método de retorno de chamada que leve ao estado Reiniciado. O sistema também
+tem controle do estado atual de cada {@link android.view.View} no layout. Portanto, se o usuário
+inserir um texto em um widget do {@link android.widget.EditText}, o conteúdo será retido e você não
+precisará salvar e restaurar.</p>
+
+<p class="note"><strong>Observação:</strong> mesmo que o sistema destrua sua atividade enquanto estiver interrompida,
+ele ainda mantém o estado do objeto {@link android.view.View} (como texto em {@link
+android.widget.EditText}) em um {@link android.os.Bundle} (um blob de pares de valores-chave) e os restaura
+se o usuário navegar de volta para a mesma instância da atividade (a <a href="recreating.html">próxima lição</a> falará mais sobre uso do {@link android.os.Bundle} para salvar
+outros dados do estado caso sua atividade seja destruída e recriada).</p>
+
+
+
+<h2 id="Start">Iniciar/reiniciar sua atividade</h2>
+
+<p>Quando sua atividade voltar ao primeiro plano do estado interrompido, ela recebe uma chamada para
+{@link android.app.Activity#onRestart()}. O sistema também chama o método {@link
+android.app.Activity#onStart()}, que acontece sempre que a atividade se tornar visível
+(ao ser reiniciada ou criada pela primeira vez). No entanto, o método {@link
+android.app.Activity#onRestart()} é chamado apenas quando a atividade é reiniciada do
+estado interrompido. Portanto, é possível usá-la para executar trabalhos de restauração especiais necessários apenas se
+a atividade tiver sido interrompida, mas não destruída.</p>
+
+<p>Dificilmente um aplicativo precisará usar {@link android.app.Activity#onRestart()} para restaurar
+o estado da atividade. Portanto, não há diretrizes para este método que se apliquem à
+população geral de aplicativos. Contudo, como espera-se que o método {@link android.app.Activity#onStop()}
+limpe todos os recursos da atividade, será necessário instanciá-los
+quando a atividade for reiniciada. Ainda assim, será necessário instanciá-los quando a atividade for criada
+pela primeira vez (quando não houver instâncias existentes da atividade). Por esse motivo, recomenda-se
+utilizar o método de retorno de chamada {@link android.app.Activity#onStart()} como contrapartida
+ao método {@link android.app.Activity#onStop()}, porque o sistema chama {@link
+android.app.Activity#onStart()} quando cria sua atividade e quando reinicia a
+atividade do estado interrompido.</p>
+
+<p>Por exemplo, como o usuário pode ter ficado longe do aplicativo por um longo período
+, o método {@link android.app.Activity#onStart()} é uma boa forma de confirmar se
+os recursos do sistema exigidos estão habilitados:</p>
+
+<pre>
+&#64;Override
+protected void onStart() {
+ super.onStart(); // Always call the superclass method first
+
+ // The activity is either being restarted or started for the first time
+ // so this is where we should make sure that GPS is enabled
+ LocationManager locationManager =
+ (LocationManager) getSystemService(Context.LOCATION_SERVICE);
+ boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
+
+ if (!gpsEnabled) {
+ // Create a dialog here that requests the user to enable GPS, and use an intent
+ // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action
+ // to take the user to the Settings screen to enable GPS when they click "OK"
+ }
+}
+
+&#64;Override
+protected void onRestart() {
+ super.onRestart(); // Always call the superclass method first
+
+ // Activity being restarted from stopped state
+}
+</pre>
+
+
+
+
+<p>Quando o sistema destrói a atividade, ele chama o método {@link android.app.Activity#onDestroy()}
+para seu {@link android.app.Activity}. Como talvez a maior parte de
+seus recursos tenha sido liberada com {@link android.app.Activity#onStop()}, no momento em que você receber a chamada para {@link
+android.app.Activity#onDestroy()}, não haverá muito a ser feito pelos aplicativos. Esse método é sua
+última chance de limpar os recursos que levariam a vazamento de memória. Portanto, certifique-se de que
+outros threads sejam destruídos e outras ações de longa execução como o rastreamento de métodos também estejam
+interrompidas.</p>
+
diff --git a/docs/html-intl/intl/pt-br/training/basics/data-storage/databases.jd b/docs/html-intl/intl/pt-br/training/basics/data-storage/databases.jd
new file mode 100644
index 0000000..37d0d43
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/training/basics/data-storage/databases.jd
@@ -0,0 +1,317 @@
+page.title=Salvando dados em bancos de dados do SQL
+page.tags=armazenamento de dados
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Esta lição ensina a</h2>
+<ol>
+ <li><a href="#DefineContract">Definir um esquema e contrato</a></li>
+ <li><a href="#DbHelper">Criar um banco de dados usando de um SQL Helper</a></li>
+ <li><a href="#WriteDbRow">Colocar informações no banco de dados</a></li>
+ <li><a href="#ReadDbRow">Ler informações de um banco de dados</a></li>
+ <li><a href="#DeleteDbRow">Excluir informações de um banco de dados</a></li>
+ <li><a href="#UpdateDbRow">Atualizar um banco de dados</a></li>
+</ol>
+
+<h2>Leia também</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#db">Usando bancos de dados</a></li>
+</ul>
+
+<!--
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/Sample.zip" class="button">Download the sample</a>
+ <p class="filename">Sample.zip</p>
+</div>
+-->
+
+</div>
+</div>
+
+
+<p>Salvar dados em um banco de dados é ideal para dados que se repetem ou estruturados,
+como informações de contato. Esta lição assume que você esteja
+familiarizado com bancos de dados do SQL em gera, e o ajuda a começar a trabalhar com bancos de dados
+do SQLite no Android. As APIs necessárias para usar um banco de dados
+no Android estão disponíveis no pacote {@link android.database.sqlite}.</p>
+
+
+<h2 id="DefineContract">Definir um esquema e contrato</h2>
+
+<p>Um dos princípios mais importantes de bancos de dados do SQL é o esquema: uma declaração
+formal de como o banco de dados é organizado. O esquema é refletido nas declarações SQL
+usadas na criação do banco de dados. É aconselhável
+criar uma classe de acompanhamento, conhecida como classe de <em>contrato</em>, que especifica claramente
+o layout do esquema de forma sistemática e autodocumentada.</p>
+
+<p>Uma classe de contrato é o contêiner das constantes que definem nomes para URIs,
+tabelas e colunas. A classe de contrato permite usar as mesmas constantes
+em outras classes no mesmo pacote. Permite que você altere o nome da
+coluna em um local e que a mudança se propague pelos seus códigos.</p>
+
+<p>Uma boa forma de organizar uma classe de contrato é colocar definições que sejam
+globais para todo o banco de dados no nível raiz da classe. Crie uma classe
+interna para cada tabela que enumera suas colunas.</p>
+
+<p class="note"><strong>Observação:</strong> implementando a interface {@link
+android.provider.BaseColumns}, sua classe interior pode herdar um campo-chave
+primário chamado {@code _ID} que algumas classes do Android, como adaptadores de cursor, esperam
+ que você tenha. Não é uma obrigatório, mas pode ajudar para um trabalho mais harmonioso com o banco de dados
+no framework do Android.</p>
+
+<p>Por exemplo, este trecho define o nome da tabela e das colunas para uma
+única tabela:</p>
+
+
+<pre>
+public final class FeedReaderContract {
+ // To prevent someone from accidentally instantiating the contract class,
+ // give it an empty constructor.
+ public FeedReaderContract() {}
+
+ /* Inner class that defines the table contents */
+ public static abstract class FeedEntry implements BaseColumns {
+ public static final String TABLE_NAME = &quot;entry&quot;;
+ public static final String COLUMN_NAME_ENTRY_ID = &quot;entryid&quot;;
+ public static final String COLUMN_NAME_TITLE = &quot;title&quot;;
+ public static final String COLUMN_NAME_SUBTITLE = &quot;subtitle&quot;;
+ ...
+ }
+}
+</pre>
+
+
+
+<h2 id="DbHelper">Criar um banco de dados usando de um SQL Helper</h2>
+
+<p>Uma vez definidos o visual dos bancos de dados, implemente métodos
+que criam e cuidam do banco de dados e das tabelas. Aqui estão algumas declarações
+comuns para criar e exclui a tabela:</P>
+
+<pre>
+private static final String TEXT_TYPE = &quot; TEXT&quot;;
+private static final String COMMA_SEP = &quot;,&quot;;
+private static final String SQL_CREATE_ENTRIES =
+ &quot;CREATE TABLE &quot; + FeedEntry.TABLE_NAME + &quot; (&quot; +
+ FeedEntry._ID + &quot; INTEGER PRIMARY KEY,&quot; +
+ FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP +
+ FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
+ ... // Any other options for the CREATE command
+ &quot; )&quot;;
+
+private static final String SQL_DELETE_ENTRIES =
+ &quot;DROP TABLE IF EXISTS &quot; + FeedEntry.TABLE_NAME;
+</pre>
+
+<p>Da mesma forma você salva arquivos no <a href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">armazenamento
+interno</a> do dispositivo, o Android armazena seu banco de dados no espaço privado do disco associado
+ao aplicativo. Seus dados estão protegidos porque, por padrão, essa área não
+pode ser acessada por outros aplicativos.</p>
+
+<p>Um conjunto de APIs está disponível na classe {@link
+android.database.sqlite.SQLiteOpenHelper}.
+Ao usar esta classe para obter referências para seu banco de dados, o sistema
+realiza operações
+de possível longa execução para criar e atualizar o banco de dados apenas quando
+necessário e <em>não durante a inicialização do aplicativo</em>. Basta chamar
+{@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase} ou
+{@link android.database.sqlite.SQLiteOpenHelper#getReadableDatabase}.</p>
+
+<p class="note"><strong>Observação:</strong> devido à possibilidade de serem de longa execução,
+certifique-se que chamar {@link
+android.database.sqlite.SQLiteOpenHelper#getWritableDatabase} ou {@link
+android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} em um thread de segundo plano,
+como {@link android.os.AsyncTask} ou {@link android.app.IntentService}.</p>
+
+<p>Para usar {@link android.database.sqlite.SQLiteOpenHelper}, crie uma subclasse que
+substitua os métodos de retorno de chamada {@link
+android.database.sqlite.SQLiteOpenHelper#onCreate onCreate()}, {@link
+android.database.sqlite.SQLiteOpenHelper#onUpgrade onUpgrade()} e {@link
+android.database.sqlite.SQLiteOpenHelper#onOpen onOpen()}. Também é possível
+implementar {@link android.database.sqlite.SQLiteOpenHelper#onDowngrade onDowngrade()},
+mas não é obrigatório.</p>
+
+<p>Por exemplo, esta é uma implementação de {@link
+android.database.sqlite.SQLiteOpenHelper} que utiliza alguns dos comandos exibidos abaixo:</p>
+
+<pre>
+public class FeedReaderDbHelper extends SQLiteOpenHelper {
+ // If you change the database schema, you must increment the database version.
+ public static final int DATABASE_VERSION = 1;
+ public static final String DATABASE_NAME = &quot;FeedReader.db&quot;;
+
+ public FeedReaderDbHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL(SQL_CREATE_ENTRIES);
+ }
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // This database is only a cache for online data, so its upgrade policy is
+ // to simply to discard the data and start over
+ db.execSQL(SQL_DELETE_ENTRIES);
+ onCreate(db);
+ }
+ public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ onUpgrade(db, oldVersion, newVersion);
+ }
+}
+</pre>
+
+<p>Para acessar seu banco de dados, instancie sua subclasse de {@link
+android.database.sqlite.SQLiteOpenHelper}:</p>
+
+<pre>
+FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());
+</pre>
+
+
+
+
+<h2 id="WriteDbRow">Colocar informações no banco de dados</h2>
+
+<p>Coloque dados no banco de dados transmitindo um objeto {@link android.content.ContentValues}
+ para o método {@link android.database.sqlite.SQLiteDatabase#insert insert()}.</p>
+
+<pre>
+// Gets the data repository in write mode
+SQLiteDatabase db = mDbHelper.getWritableDatabase();
+
+// Create a new map of values, where column names are the keys
+ContentValues values = new ContentValues();
+values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id);
+values.put(FeedEntry.COLUMN_NAME_TITLE, title);
+values.put(FeedEntry.COLUMN_NAME_CONTENT, content);
+
+// Insert the new row, returning the primary key value of the new row
+long newRowId;
+newRowId = db.insert(
+ FeedEntry.TABLE_NAME,
+ FeedEntry.COLUMN_NAME_NULLABLE,
+ values);
+</pre>
+
+<p>Este primeiro argumento para {@link android.database.sqlite.SQLiteDatabase#insert insert()}
+é apenas o nome da tabela. O segundo argumento fornece
+o nome de uma coluna em que o framework pode inserir NULL caso o
+{@link android.content.ContentValues} esteja vazio (se você definir como {@code "null"},
+o framework não inserirá uma linha quando não houver valores).</p>
+
+
+
+
+<h2 id="ReadDbRow">Ler informações de um banco de dados</h2>
+
+<p>Para ler de um banco de dados, utilize o método {@link android.database.sqlite.SQLiteDatabase#query query()}
+, transmitindo seus critérios de seleção e colunas desejadas.
+O método combina elementos de {@link android.database.sqlite.SQLiteDatabase#insert insert()}
+ e {@link android.database.sqlite.SQLiteDatabase#update update()}, exceto que a lista da coluna
+define os dados que serão analisados e não os dados a serem inseridos. Os resultados da consulta
+são retornados em um objeto {@link android.database.Cursor}.</p>
+
+<pre>
+SQLiteDatabase db = mDbHelper.getReadableDatabase();
+
+// Define a <em>projection</em> that specifies which columns from the database
+// you will actually use after this query.
+String[] projection = {
+ FeedEntry._ID,
+ FeedEntry.COLUMN_NAME_TITLE,
+ FeedEntry.COLUMN_NAME_UPDATED,
+ ...
+ };
+
+// How you want the results sorted in the resulting Cursor
+String sortOrder =
+ FeedEntry.COLUMN_NAME_UPDATED + " DESC";
+
+Cursor c = db.query(
+ FeedEntry.TABLE_NAME, // The table to query
+ projection, // The columns to return
+ selection, // The columns for the WHERE clause
+ selectionArgs, // The values for the WHERE clause
+ null, // don't group the rows
+ null, // don't filter by row groups
+ sortOrder // The sort order
+ );
+</pre>
+
+<p>Para ver uma linha no cursor, utilize um dos métodos de movimento {@link android.database.Cursor},
+que sempre deverão ser chamados antes de começar a ler valores. Geralmente, deve-se iniciar
+chamando {@link android.database.Cursor#moveToFirst}, que coloca a “posição leitura” na
+primeira entrada nos resultados. Para cada linha, você pode ler um valor de coluna chamando um dos métodos GET
+{@link android.database.Cursor}, como {@link android.database.Cursor#getString
+getString()} ou {@link android.database.Cursor#getLong getLong()}. Para cada um dos métodos GET,
+você deve transmitir a posição de índice da coluna desejada, que pode ser obtida chamando
+{@link android.database.Cursor#getColumnIndex getColumnIndex()} ou
+{@link android.database.Cursor#getColumnIndexOrThrow getColumnIndexOrThrow()}.
+Por exemplo:</p>
+
+<pre>
+cursor.moveToFirst();
+long itemId = cursor.getLong(
+ cursor.getColumnIndexOrThrow(FeedEntry._ID)
+);
+</pre>
+
+
+
+
+<h2 id="DeleteDbRow">Excluir informações de um banco de dados</h2>
+
+<p>Para excluir linhas de uma tabela, forneça os critérios de seleção que as
+identifique. A API do banco de dados oferece um mecanismo para criar
+critérios de seleção que protegem contra injeção do SQL. O mecanismo divide a
+especificação da seleção em uma cláusula e argumentos de seleção. A
+cláusula define a coluna a se olhar e também permite combinar testes de
+coluna. Os argumentos são valores para testes comparativos que são dependentes dentro de uma cláusula.
+Como o resultado não é tratado da mesma forma que uma declaração SQL comum, ele fica
+imune à injeção de SQL.</p>
+
+<pre>
+// Define 'where' part of query.
+String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + &quot; LIKE ?&quot;;
+// Specify arguments in placeholder order.
+String[] selectionArgs = { String.valueOf(rowId) };
+// Issue SQL statement.
+db.delete(table_name, selection, selectionArgs);
+</pre>
+
+
+
+<h2 id="UpdateDbRow">Atualizar um banco de dados</h2>
+
+<p>Quando precisar alterar um subconjunto dos valores de seu banco de dados, utilize o método {@link
+android.database.sqlite.SQLiteDatabase#update update()}.</p>
+
+<p>A atualização da tabela combina a sintaxe de valores do conteúdo de {@link
+android.database.sqlite.SQLiteDatabase#insert insert()} com a sintaxe {@code where} de
+{@link android.database.sqlite.SQLiteDatabase#delete delete()}.</p>
+
+<pre>
+SQLiteDatabase db = mDbHelper.getReadableDatabase();
+
+// New value for one column
+ContentValues values = new ContentValues();
+values.put(FeedEntry.COLUMN_NAME_TITLE, title);
+
+// Which row to update, based on the ID
+String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + &quot; LIKE ?&quot;;
+String[] selectionArgs = { String.valueOf(rowId) };
+
+int count = db.update(
+ FeedReaderDbHelper.FeedEntry.TABLE_NAME,
+ values,
+ selection,
+ selectionArgs);
+</pre>
+
diff --git a/docs/html-intl/intl/pt-br/training/basics/data-storage/files.jd b/docs/html-intl/intl/pt-br/training/basics/data-storage/files.jd
new file mode 100644
index 0000000..d071d39
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/training/basics/data-storage/files.jd
@@ -0,0 +1,379 @@
+page.title=Salvando arquivos
+page.tags=armazenamento de dados
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Esta lição ensina a</h2>
+<ol>
+ <li><a href="#InternalVsExternalStorage">Escolher entre armazenamento interno e externo</a></li>
+ <li><a href="#GetWritePermission">Obter permissões para armazenamento externo</a></li>
+ <li><a href="#WriteInternalStorage">Salvar arquivos em armazenamento interno</a></li>
+ <li><a href="#WriteExternalStorage">Salvar arquivos em armazenamento externo</a></li>
+ <li><a href="#GetFreeSpace">Consultar espaço livre</a></li>
+ <li><a href="#DeleteFile">Excluir um arquivo</a></li>
+</ol>
+
+<h2>Leia também</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">Utilizando armazenamento
+interno</a></li>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#filesExternal">Utilizando armazenamento
+externo</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>O Android usa um sistema de arquivos
+parecido com sistemas de arquivos em disco de outras plataformas. Esta lição explica
+como trabalhar com o sistema de arquivos Android para ler e gravar arquivos com APIs {@link java.io.File}
+.</p>
+
+<p>Um objeto {@link java.io.File} é adequado para ler ou gravar grandes quantidades de dados em
+ordens crescente sem pular nenhum item. Por exemplo, é bom para arquivos de imagens ou
+qualquer troca executada por uma rede.</p>
+
+<p>Esta lição demonstra como executar tarefas básicas relacionadas a arquivos em seu aplicativo.
+Assume-se que você já esteja familiarizado com os fundamentos do sistema de arquivos Linux e com
+APIs de entrada/saída de arquivos padrão no {@link java.io}.</p>
+
+
+<h2 id="InternalVsExternalStorage">Escolher entre armazenamento interno e externo</h2>
+
+<p>Todos os dispositivos Android têm duas áreas de armazenamento de arquivos: armazenamento “interno” e “externo”. Estes nomes
+têm origem no início do Android, quando a maior parte de seus dispositivos oferecia memória embutida não volátil
+(armazenamento interno), além de uma mídia de armazenamento removível, como micro cartões SD (armazenamento externo).
+Alguns dispositivos dividem o espaço de armazenamento permanente em partições “interna” e “externa”. Assim, mesmo
+sem uma mídia de armazenamento removível, sempre há dois espaços de armazenamento e
+o comportamento da API permanece inalterado independentemente da remoção do armazenamento externo.
+A lista a seguir resume as principais informações sobre cada tipo de espaço de armazenamento.</p>
+
+<div class="col-5" style="margin-left:0">
+<p><b>Armazenamento interno:</b></p>
+<ul>
+<li>Está sempre disponível.</li>
+<li>Por padrão, os arquivos salvos aqui podem apenas ser acessados pelo seu aplicativo.</li>
+<li>Quando o usuário desinstala o aplicativo, o sistema exclui todos os arquivos do aplicativo salvos no
+armazenamento interno.</li>
+</ul>
+<p>O armazenamento interno funciona melhor quando você deseja garantir que o usuário nem outros aplicativos
+tenham acesso aos seus arquivos.</p>
+</div>
+
+<div class="col-7" style="margin-right:0">
+<p><b>Armazenamento externo:</b></p>
+<ul>
+<li>Não está sempre disponível porque o usuário pode montar o armazenamento externo, como um armazenamento USB,
+ e em alguns casos, removê-lo do dispositivo.</li>
+<li>É de leitura universal, ou seja,
+arquivos salvos aqui podem ser lidos em outros dispositivos.</li>
+<li>Quando o usuário desinstala o aplicativo, o sistema exclui todos os arquivos do aplicativo salvos aqui
+apenas se estiverem salvos no diretório de {@link android.content.Context#getExternalFilesDir
+getExternalFilesDir()}.</li>
+</ul>
+<p>O armazenamento externo é o melhor
+local para arquivos que não exigem acesso restrito e para os arquivos que você deseja compartilhar
+com outros aplicativos ou permitir que o usuário acesse através com um computador.</p>
+</div>
+
+
+<p class="note" style="clear:both">
+<strong>Dica:</strong> embora os aplicativos sejam instalados no armazenamento interno por
+padrão, é possível especificar o atributo <a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code
+android:installLocation}</a> em seu manifesto para que o aplicativo
+seja instalado no armazenamento externo. Os usuários se beneficiam dessa opção quando o tamanho do APK é muito grande e
+ele dispõe de maior espaço em armazenamento externo do que interno. Para obter mais
+informações, consulte <a href="{@docRoot}guide/topics/data/install-location.html">Local de instalação do aplicativo</a>.</p>
+
+
+<h2 id="GetWritePermission">Obter permissões para armazenamento externo</h2>
+
+<p>Para gravar no armazenamento externo, você deve solicitar a
+permissão {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} em seu <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">arquivo de manifesto</a>:</p>
+
+<pre>
+&lt;manifest ...>
+ &lt;uses-permission android:name=&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot; /&gt;
+ ...
+&lt;/manifest>
+</pre>
+
+<div class="caution"><p><strong>Cuidado:</strong>
+atualmente, os aplicativos podem ler o armazenamento externo
+sem precisar de permissão especial. No entanto, isso será alterado em lançamentos futuros. Se seu aplicativo precisar
+ler o armazenamento externo (mas não gravar nele), será necessário declarar a permissão {@link
+android.Manifest.permission#READ_EXTERNAL_STORAGE}. Para garantir que o aplicativo continue
+a funcionar adequadamente, declare essa permissão agora antes que as mudanças entrem em vigor.</p>
+<pre>
+&lt;manifest ...>
+ &lt;uses-permission android:name=&quot;android.permission.READ_EXTERNAL_STORAGE&quot; /&gt;
+ ...
+&lt;/manifest>
+</pre>
+<p>No entanto, se seu aplicativo usa a permissão {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}
+, já existe uma permissão implícita para leitura do armazenamento externo.</p>
+</div>
+
+<p>Não é necessária permissão para salvar arquivos no armazenamento
+interno. Seu aplicativo sempre terá permissão para ler e
+gravar arquivos em seu diretório de armazenamento interno.</p>
+
+
+
+
+
+<h2 id="WriteInternalStorage">Salvar arquivos em armazenamento interno</h2>
+
+<p>Ao salvar um arquivo no armazenamento interno, você pode obter o diretório adequado como um
+{@link java.io.File} chamando um destes dois métodos:</p>
+
+<dl>
+ <dt>{@link android.content.Context#getFilesDir}</dt>
+ <dd>Retorna um {@link java.io.File} que representa um diretório interno para seu aplicativo.</dd>
+ <dt>{@link android.content.Context#getCacheDir}</dt>
+ <dd>Retorna um {@link java.io.File} que representa um diretório interno para os arquivos de cache temporários
+de seu aplicativo. Certifique-se de excluir cada arquivo assim que não
+for mais necessário e estabeleça um limite de tamanho razoável para a quantidade de memória usada em um determinado
+período de tempo, como 1MB. Se o sistema começar a ficar com pouco espaço de armazenamento, ele poderá excluir arquivos de cache
+sem avisar.</dd>
+</dl>
+
+<p>Para criar um novo arquivo em um desses diretórios, use o construtor {@link
+android.Manifest.permission#READ_EXTERNAL_STORAGE}, transmitindo o {@link java.io.File} fornecido por um
+dos métodos acima que especifica o diretório de armazenamento interno. Por exemplo:</p>
+
+<pre>
+File file = new File(context.getFilesDir(), filename);
+</pre>
+
+<p>Uma outra alternativa é chamar {@link
+android.content.Context#openFileOutput openFileOutput()} para obter um {@link java.io.FileOutputStream}
+que grave em um arquivo salvo no seu diretório interno. O exemplo a seguir
+mostra como gravar texto em um arquivo:</p>
+
+<pre>
+String filename = "myfile";
+String string = "Hello world!";
+FileOutputStream outputStream;
+
+try {
+ outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
+ outputStream.write(string.getBytes());
+ outputStream.close();
+} catch (Exception e) {
+ e.printStackTrace();
+}
+</pre>
+
+<p>Em alternativa, caso precise colocar arquivos em cache, use {@link
+java.io.File#createTempFile createTempFile()}. Por exemplo, o método a seguir extrai o
+nome do arquivo de {@link java.net.URL} e cria um arquivo com o mesmo nome
+no diretório de cache interno de seu aplicativo.</p>
+
+<pre>
+public File getTempFile(Context context, String url) {
+ File file;
+ try {
+ String fileName = Uri.parse(url).getLastPathSegment();
+ file = File.createTempFile(fileName, null, context.getCacheDir());
+ catch (IOException e) {
+ // Error while creating file
+ }
+ return file;
+}
+</pre>
+
+<p class="note"><strong>Observação:</strong>
+o diretório de armazenamento interno do seu aplicativo é especificado
+pelo nome do pacote do aplicativo em um local específico do sistema de arquivos Android.
+Teoricamente, outros aplicativos poderão ler seus arquivos internos se você definir
+o arquivo para modo leitura. No entanto, o outro aplicativo também precisaria saber o nome do pacote
+do seu aplicativo e os nomes dos arquivos. Outros aplicativos não podem navegar nos diretórios internos e não têm
+permissão para ler ou gravar a menos que os arquivos sejam explicitamente definidos para permitir tais ações. Portanto,
+desde que você utilize {@link android.content.Context#MODE_PRIVATE} para seus arquivos no armazenamento interno,
+eles não ficarão acessíveis a outros aplicativos.</p>
+
+
+
+
+
+<h2 id="WriteExternalStorage">Salvar arquivos em armazenamento externo</h2>
+
+<p>Como o armazenamento externo pode ficar indisponível, como se o usuário ativar o
+armazenamento no PC ou remover o cartão SD que fornece armazenamento externo,
+você deve sempre verificar se o volume está disponível antes de acessá-lo. Consulte o estado de armazenamento
+externo chamando {@link android.os.Environment#getExternalStorageState}. Se o estado
+retornado for igual a {@link android.os.Environment#MEDIA_MOUNTED}, os arquivos poderão ser lidos
+e gravados. Os métodos a seguir ajudam a determinar a disponibilidade
+de armazenamento:</p>
+
+<pre>
+/* Checks if external storage is available for read and write */
+public boolean isExternalStorageWritable() {
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+ return false;
+}
+
+/* Checks if external storage is available to at least read */
+public boolean isExternalStorageReadable() {
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
+ }
+ return false;
+}
+</pre>
+
+<p>Embora o usuário e outros aplicativos possam modificar o armazenamento externo, há duas
+categorias de arquivos que deverão ser salvas aqui:</p>
+
+<dl>
+ <dt>Arquivos públicos</dt>
+ <dd>Arquivos que
+precisam estar livremente disponíveis ao usuário e outros aplicativos. Ao desinstalar o aplicativo,
+o usuário deve continuar a ter acesso a esses arquivos.
+ <p>Por exemplo, fotos capturadas pelo aplicativo ou outros arquivos baixados.</p>
+ </dd>
+ <dt>Arquivos privados</dt>
+ <dd>Arquivos que pertencem ao aplicativo e que devem ser excluídos na desinstalação
+. Embora esses arquivos estejam teoricamente à disposição do usuário e de outros aplicativo por estarem
+no armazenamento externo, na verdade são arquivos que não têm valor para o usuário
+fora do aplicativo. Ao desinstalar o aplicativo, o sistema exclui
+todos os arquivos no diretório privado externo do aplicativo.
+ <p>Por exemplo, recursos adicionais baixados através do aplicativo ou arquivos de mídia temporários.</p>
+ </dd>
+</dl>
+
+<p>Para salvar arquivos públicos no armazenamento externo, use o método
+{@link android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()} para obter um {@link java.io.File} que representa
+o diretório correto no armazenamento externo. O método exige um argumento que especifica
+o tipo de arquivo que se deseja salvar para que possa ser logicamente organizado com outros arquivos públicos
+, como {@link android.os.Environment#DIRECTORY_MUSIC} ou {@link
+android.os.Environment#DIRECTORY_PICTURES}. Por exemplo:</p>
+
+<pre>
+public File getAlbumStorageDir(String albumName) {
+ // Get the directory for the user's public pictures directory.
+ File file = new File(Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES), albumName);
+ if (!file.mkdirs()) {
+ Log.e(LOG_TAG, "Directory not created");
+ }
+ return file;
+}
+</pre>
+
+
+<p>Se você deseja salvar arquivos privados do aplicativo, obtenha o
+diretório correto chamando {@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()} e informe um nome indicando
+o tipo de diretório desejado. Cada diretório criado dessa forma é adicionado ao diretório principal
+que contém todos os arquivos do armazenamento externo do aplicativo que o sistema exclui quando o
+usuário faz a desinstalação.</p>
+
+<p>Por exemplo, este é um método que pode ser usado para criar um diretório para um álbum de fotos individual:</p>
+
+<pre>
+public File getAlbumStorageDir(Context context, String albumName) {
+ // Get the directory for the app's private pictures directory.
+ File file = new File(context.getExternalFilesDir(
+ Environment.DIRECTORY_PICTURES), albumName);
+ if (!file.mkdirs()) {
+ Log.e(LOG_TAG, "Directory not created");
+ }
+ return file;
+}
+</pre>
+
+<p>Se nenhum dos nomes de subdiretórios predefinidos se adequa aos arquivos, chame {@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()} e transmita {@code null}. Isso
+retorna o diretório raiz para o diretório privado do aplicativo no armazenamento externo.</p>
+
+<p>Lembre-se de que {@link android.content.Context#getExternalFilesDir getExternalFilesDir()}
+cria um diretório dentro de um diretório que é excluído quando o usuário desinstala o aplicativo.
+Se os arquivos salvos precisarem estar disponíveis após a desinstalação do
+aplicativo, como
+quando seu aplicativo é uma câmera e o usuário deseja manter as fotos, use {@link android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()}.</p>
+
+
+<p>Independentemente do uso de {@link
+android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()} para arquivos compartilhados ou
+{@link android.content.Context#getExternalFilesDir
+getExternalFilesDir()} para arquivos privados do aplicativo, é importante usar
+os nomes de diretório fornecidos pelas constantes de API, como
+{@link android.os.Environment#DIRECTORY_PICTURES}. Esses nomes de diretório garantem
+que os arquivos sejam tratados de forma adequada pelo sistema. Por exemplo, arquivos salvos em {@link
+android.os.Environment#DIRECTORY_RINGTONES} são categorizados pelo scanner de mídia dos sistema como toques
+e não como música.</p>
+
+
+
+
+<h2 id="GetFreeSpace">Consultar espaço livre</h2>
+
+<p>Se você já souber antecipadamente a quantidade de dados a ser salvo, descubra se
+há espaço disponível suficiente sem fazer com que um {@link
+java.io.IOException} chame {@link java.io.File#getFreeSpace} ou {@link
+java.io.File#getTotalSpace}. Esses métodos informam o espaço disponível atual e o
+espaço total no volume de armazenamento. Essa informação ajuda a evitar o preenchimento
+do volume de armazenamento além de um determinado limite.</p>
+
+<p>No entanto, o sistema não garante que será possível gravar a quantidade de bytes indicada
+por {@link java.io.File#getFreeSpace}. Se o número retornado tiver
+alguns MB além do tamanho dos dados que deseja salvar ou se o sistema de arquivos
+estiver abaixo de 90% cheio, é possível continuar com segurança.
+Caso contrário, não grave no armazenamento.</p>
+
+<p class="note"><strong>Observação:</strong> não é obrigatório verificar a quantidade de espaço disponível
+antes de salvar o arquivo. É possível tentar gravar o arquivo diretamente e depois
+obter um {@link java.io.IOException}, se houver. Essa ação é recomendada
+caso você não saiba exatamente quanto espaço será necessário. Por exemplo, se
+você alterar a codificação do arquivo antes de salvá-lo convertendo uma imagem PNG em
+JPEG, não é possível saber o tamanho do arquivo antecipadamente.</p>
+
+
+
+
+<h2 id="DeleteFile">Excluir um arquivo</h2>
+
+<p>Sempre exclua arquivos que não sejam mais necessários. A forma mais simples de apagar um
+arquivo é fazer com que o arquivo de referência aberto chame {@link java.io.File#delete} por conta própria.</p>
+
+<pre>
+myFile.delete();
+</pre>
+
+<p>Se o arquivo estiver salvo em armazenamento interno, é possível solicitar ao {@link android.content.Context} para localizar e
+excluir o arquivo chamando {@link android.content.Context#deleteFile deleteFile()}:</p>
+
+<pre>
+myContext.deleteFile(fileName);
+</pre>
+
+<div class="note">
+<p><strong>Observação:</strong> quando o usuário desinstala o aplicativo, o sistema Android também
+exclui:</p>
+<ul>
+<li>Todos os arquivos salvos no armazenamento interno</li>
+<li>Todos os arquivos salvos no armazenamento externo usando {@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()}.</li>
+</ul>
+<p>No entanto, recomenda-se exclui manualmente todos os arquivos em cache criados com
+{@link android.content.Context#getCacheDir()} regularmente e
+outros arquivos que não sejam mais necessários.</p>
+</div>
+
diff --git a/docs/html-intl/intl/pt-br/training/basics/data-storage/index.jd b/docs/html-intl/intl/pt-br/training/basics/data-storage/index.jd
new file mode 100644
index 0000000..2b88ce1
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/training/basics/data-storage/index.jd
@@ -0,0 +1,57 @@
+page.title=Salvando dados
+page.tags=armazenamento de dados,arquivos,sql,basededados,preferências
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Dependências e pré-requisitos</h2>
+<ul>
+ <li>Android 1.6 (API Nível 4) ou superior</li>
+ <li>Familiaridade com coleções de valores-chave do Map</li>
+ <li>Familiaridade com API de E/S de arquivos Java</li>
+ <li>Familiaridade com bancos de dados do SQL</li>
+</ul>
+
+<h2>Leia também</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html">Opções de armazenamento</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>A maioria dos aplicativos Android precisa salvar dados, mesmo que seja apenas para salvar informações sobre o estado do aplicativo
+durante {@link android.app.Activity#onPause onPause()} para que o progresso do usuário não seja perdido. A maior parte
+dos aplicativos não triviais também precisa salvar configurações do usuário e alguns aplicativos precisam gerenciar grandes
+quantidades de informação em arquivos e bancos de dados. Esta aula apresenta as
+principais opções de armazenamento de dados no Android, incluindo:</p>
+
+<ul>
+ <li>Como salvar pares de valores-chave de tipos de dados simples em um arquivo de preferências
+compartilhadas</li>
+ <li>Como salvar arquivos arbitrários no sistema de arquivos do Android</li>
+ <li>Como usar bancos de dados gerenciadas pelo SQLite</li>
+</ul>
+
+
+<h2>Lições</h2>
+
+<dl>
+ <dt><b><a href="shared-preferences.html">Salvando conjuntos de valores-chave</a></b></dt>
+ <dd>Aprenda a como usar um arquivo de preferências compartilhadas para armazenar pequenas quantidades de informação em pares de
+valores-chave.</dd>
+
+ <dt><b><a href="files.html">Salvando arquivos</a></b></dt>
+ <dd>Aprenda a como salvar um arquivo básico, como para armazenar longas sequências de dados que
+ são geralmente lidas em ordem.</dd>
+
+ <dt><b><a href="databases.html">Salvando dados em bancos de dados do SQL</a></b></dt>
+ <dd>Aprenda a usar o banco de dados do SQLite para ler e gravar dados estruturados.</dd>
+
+</dl>
diff --git a/docs/html-intl/intl/pt-br/training/basics/data-storage/shared-preferences.jd b/docs/html-intl/intl/pt-br/training/basics/data-storage/shared-preferences.jd
new file mode 100644
index 0000000..0c84487
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/training/basics/data-storage/shared-preferences.jd
@@ -0,0 +1,120 @@
+page.title=Salvando conjuntos de valor-chave
+page.tags=armazenamento de dados
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Esta lição ensina a</h2>
+<ol>
+ <li><a href="#GetSharedPreferences">Obter um identificador para preferências compartilhadas</a></li>
+ <li><a href="#WriteSharedPreference">Gravar em preferências compartilhadas</a></li>
+ <li><a href="#ReadSharedPreference">Ler de preferências compartilhadas</a></li>
+</ol>
+
+<h2>Leia também</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#pref">Usando preferências compartilhadas</a></li>
+</ul>
+
+</div>
+</div>
+
+
+<p>Caso você tenha uma coleção relativamente pequena de valores-chave para salvar,
+use as APIs {@link android.content.SharedPreferences}.
+Um objeto {@link android.content.SharedPreferences} indica um arquivo que contém
+pares de valores-chave e fornece métodos simples para ler e gravar. Cada arquivo
+{@link android.content.SharedPreferences} é
+gerenciado pelo framework e pode ser privado ou compartilhado.</p>
+
+<p>Essa lição mostra como usar as APIs {@link android.content.SharedPreferences} para armazenar e
+recuperar valores simples.</p>
+
+<p class="note"><strong>Observação:</strong> as APIs {@link android.content.SharedPreferences} são
+usadas apenas para leitura e gravação de pares de valores-chave e não devem ser confundidas com as APIs
+{@link android.preference.Preference}, que ajudam a criar uma interface do usuário
+para as configurações do seu aplicativo (embora usem {@link android.content.SharedPreferences} como
+implementação para salvar as configurações de aplicativo). Para obter mais informação sobre uso de APIs {@link
+android.preference.Preference}, consulte a guia <a href="{@docRoot}guide/topics/ui/settings.html">Configurações</a>.</p>
+
+<h2 id="GetSharedPreferences">Obter um identificador para preferências compartilhadas</h2>
+
+<p>É possível criar um novo arquivo de preferência compartilhada ou acessar um existente
+chamando um destes dois métodos:</p>
+<ul>
+ <li>{@link android.content.Context#getSharedPreferences(String,int)
+getSharedPreferences()} &mdash; Use este método se precisar identificar vários arquivos de preferência compartilhada
+por nome, que devem ser especificados com o primeiro parâmetro. É possível chamá-lo por qualquer
+{@link android.content.Context} em seu aplicativo.</li>
+ <li>{@link android.app.Activity#getPreferences(int) getPreferences()} &mdash; Use este método por um
+{@link android.app.Activity} se precisar
+usar apenas um arquivo de preferência compartilhada para a atividade. Como ele retorna um arquivo de preferência compartilhada
+padrão que pertence à atividade, não é necessário fornecer um nome.</li>
+</ul>
+
+<p>Por exemplo, o código a seguir é executado dentro de um {@link android.app.Fragment}.
+Ele acessa o arquivo de preferências compartilhadas que é
+identificado pela cadeia de caracteres de recursos {@code R.string.preference_file_key} e o abre usando
+o modo privado para que o arquivo possa ser acessado apenas pelo seu aplicativo.</p>
+
+<pre>
+Context context = getActivity();
+SharedPreferences sharedPref = context.getSharedPreferences(
+ getString(R.string.preference_file_key), Context.MODE_PRIVATE);
+</pre>
+
+<p>Ao nomear seus arquivos de preferência compartilhada, você deve usar um nome que seja identificável exclusivamente
+para o aplicativo, como {@code "com.example.myapp.PREFERENCE_FILE_KEY"}</p>
+
+<p>Em alternativa, caso precise apenas de um arquivo de preferência compartilhada para sua atividade, use o método
+{@link android.app.Activity#getPreferences(int) getPreferences()}:</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+</pre>
+
+<p class="caution"><strong>Cuidado:</strong> se você criar um arquivo de preferência compartilhada
+com {@link android.content.Context#MODE_WORLD_READABLE} ou {@link
+android.content.Context#MODE_WORLD_WRITEABLE}, qualquer outro aplicativo que conhecer o identificador de arquivo
+poderá acessar seus dados.</p>
+
+
+<h2 id="WriteSharedPreference">Gravar em preferências compartilhadas</h2>
+
+<p>Para gravar em um arquivo de preferência compartilhada, crie um {@link
+android.content.SharedPreferences.Editor} chamando {@link
+android.content.SharedPreferences#edit} em seu {@link android.content.SharedPreferences}.</p>
+
+<p>Transmita as chaves e os valores que deseja gravar com métodos como {@link
+android.content.SharedPreferences.Editor#putInt putInt()} e {@link
+android.content.SharedPreferences.Editor#putString putString()}. Chame {@link
+android.content.SharedPreferences.Editor#commit} para salvar as alterações. Por exemplo:</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+SharedPreferences.Editor editor = sharedPref.edit();
+editor.putInt(getString(R.string.saved_high_score), newHighScore);
+editor.commit();
+</pre>
+
+
+<h2 id="ReadSharedPreference">Ler de preferências compartilhadas</h2>
+
+<p>Para recuperar valores de um arquivo de preferência compartilhada, chame métodos como {@link
+android.content.SharedPreferences#getInt getInt()} e {@link
+android.content.SharedPreferences#getString getString()}, fornecendo a chave para o valor
+desejado e opcionalmente um valor padrão para retornar caso a chave não esteja
+presente. Por exemplo:</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+int defaultValue = getResources().getInteger(R.string.saved_high_score_default);
+long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue);
+</pre>
+
diff --git a/docs/html-intl/intl/pt-br/training/basics/intents/filters.jd b/docs/html-intl/intl/pt-br/training/basics/intents/filters.jd
new file mode 100644
index 0000000..73f0b84
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/training/basics/intents/filters.jd
@@ -0,0 +1,236 @@
+page.title=Permitindo que outros aplicativos iniciem sua atividade
+page.tags=intenções
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>Esta lição ensina a</h2>
+<ol>
+ <li><a href="#AddIntentFilter">Adicionar um filtro de intenções</a></li>
+ <li><a href="#HandleIntent">Responder à intenção em sua atividade</a></li>
+ <li><a href="#ReturnResult">Retornar um resultado</a></li>
+</ol>
+
+<h2>Leia também</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">Compartilhando dados simples</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">Compartilhando arquivos</a>
+</ul>
+ </div>
+</div>
+
+<p>As duas lições anteriores enfatizaram um aspecto: iniciar a atividade de outro aplicativo pelo
+seu aplicativo. Mas se seu aplicativo puder executar uma ação que pode ser útil para outro aplicativo,
+ele precisa estar preparado para responder às solicitações de ação de outros aplicativos. Por exemplo, se
+construir um aplicativo social que compartilhe mensagens ou fotos com os amigos do usuário, é interessante
+que ele possa responder à intenção {@link android.content.Intent#ACTION_SEND} para que os usuários consigam iniciar uma
+ação de “compartilhar” por outro aplicativo e iniciar seu aplicativo para executar a ação.</p>
+
+<p>Para permitir que outros aplicativos iniciem sua atividade, adicione um elemento <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter&gt;}</a>
+em seu arquivo de manifesto para o elemento <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> correspondente.</p>
+
+<p>Quando seu aplicativo é instalado em um dispositivo, o sistema identifica seu filtro de
+intenções e adiciona a informação a um catálogo interno de intenções suportado por todos os aplicativos instalados.
+Quando um aplicativo chama {@link android.app.Activity#startActivity
+startActivity()} ou {@link android.app.Activity#startActivityForResult startActivityForResult()},
+com uma intenção implícita, o sistema encontra qual atividade (ou atividades) pode responder à
+intenção.</p>
+
+
+
+<h2 id="AddIntentFilter">Adicionar um filtro de intenções</h2>
+
+<p>Para definir adequadamente a quais intenções sua atividade responderá, cada filtro de intenções adicionado
+deverá ser o mais específico possível em termos de tipo de ação e dados aceitos pela
+atividade.</p>
+
+<p>O sistema pode enviar uma determinada {@link android.content.Intent} para uma atividade se ela tiver
+um filtro de intenções que atenda aos seguintes critérios do objeto {@link android.content.Intent}:</p>
+
+<dl>
+ <dt>Ação</dt>
+ <dd>Uma cadeia de caracteres que dá nome a ação a ser executada. Geralmente, um dos valores definidos para a plataforma
+como {@link android.content.Intent#ACTION_SEND} ou {@link android.content.Intent#ACTION_VIEW}.
+ <p>Especifique-o em seu filtro de intenções com o elemento <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code &lt;action&gt;}</a>.
+O valor especificado neste elemento deve ser o nome completo da cadeia de caracteres para a ação e não a
+API constante (veja exemplos abaixo).</p></dd>
+
+ <dt>Dados</dt>
+ <dd>A descrição dos dados associados à intenção.
+ <p>Especifique-a em seu filtro de intenções com o elemento <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data&gt;}</a>. Através de um
+ou mais atributos neste elemento, você pode especificar apenas o tipo MIME, apenas um prefixo de URI,
+apenas um esquema de URI ou uma combinação destes e outros elementos que indicam o tipo de dados
+aceito.</p>
+ <p class="note"><strong>Observação:</strong> se não precisar especificar os dados
+{@link android.net.Uri} (como quando sua atividade responde a outros tipos de dados “extra”, em vez
+do URI), especifique apenas o atributo {@code android:mimeType} para declarar o tipo de
+dado que sua atividade trata, como {@code text/plain} ou {@code image/jpeg}.</p>
+</dd>
+ <dt>Categoria</dt>
+ <dd>Oferece uma outra forma de caracterizar a atividade que trata a intenção, geralmente relacionada
+ao gesto do usuário ou localização onde foi iniciada. Há diferentes categorias
+compatíveis com o sistema, mas a maioria raramente é utilizada. No entanto, todas as intenções implícitas são definidas com
+{@link android.content.Intent#CATEGORY_DEFAULT} por padrão.
+ <p>Especifique-a em seu filtro de intenções com o elemento <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code &lt;category&gt;}</a>
+.</p></dd>
+</dl>
+
+<p>Em seu filtro de intenções, declare quais critérios serão aceitos por sua atividade
+informando cada um deles com elementos XML correspondentes aninhados no elemento <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter&gt;}</a>
+.</p>
+
+<p>Este é um exemplo de atividade com filtro de intenções que responde à intenção {@link
+android.content.Intent#ACTION_SEND} quando o tipo de dado é texto ou imagem:</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;data android:mimeType="image/*"/>
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p>Cada intenção em entrada especifica apenas uma ação e um tipo de dado, mas pode-se declarar
+múltiplas instâncias dos elementos <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> e <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code
+&lt;data&gt;}</a> em cada
+<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a>.</p>
+
+<p>Se dois pares de ação e dados fores mutuamente exclusivos em
+seus comportamentos, crie filtros de intenções separados para especificar quais ações são aceitáveis
+quando pareadas com qual tipo de dado.</p>
+
+<p>Imagine que sua atividade responda à ambos, texto e imagem, para intenções {@link
+android.content.Intent#ACTION_SEND} e {@link
+android.content.Intent#ACTION_SENDTO}. Nesse caso, defina dois
+filtros de intenções separados para as duas ações porque uma intenção {@link
+android.content.Intent#ACTION_SENDTO} deve usar os dados {@link android.net.Uri} para especificar
+o endereço do destinatário utilizando o esquema do URI {@code send} ou {@code sendto}. Por exemplo:</p>
+
+<pre>
+&lt;activity android:name="ShareActivity">
+ &lt;!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.SENDTO"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:scheme="sms" />
+ &lt;data android:scheme="smsto" />
+ &lt;/intent-filter>
+ &lt;!-- filter for sending text or images; accepts SEND action and text or image data -->
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.SEND"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:mimeType="image/*"/>
+ &lt;data android:mimeType="text/plain"/>
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p class="note"><strong>Observação:</strong> para receber intenções implícitas, inclua a categoria
+{@link android.content.Intent#CATEGORY_DEFAULT} no filtro de intenções. Os métodos {@link
+android.app.Activity#startActivity startActivity()} e {@link
+android.app.Activity#startActivityForResult startActivityForResult()} tratam todas as intenções como se elas tivessem
+declarado a categoria {@link android.content.Intent#CATEGORY_DEFAULT}. Se você não a declarar
+em seu filtro de intenções, nenhuma intenção implícita resolverá sua atividade.</p>
+
+<p>Para obter mais informações sobre o envio e recebimento de intenções {@link android.content.Intent#ACTION_SEND}
+que realizam comportamentos de compartilhamento social, veja a lição <a href="{@docRoot}training/sharing/receive.html">Recebendo dados simples de outros aplicativos</a>.</p>
+
+
+<h2 id="HandleIntent">Responder à intenção em sua atividade</h2>
+
+<p>Para decidir qual ação tomar em sua atividade, leia a {@link
+android.content.Intent} utilizada para iniciá-la.</p>
+
+<p>Quando sua atividade iniciar, chame {@link android.app.Activity#getIntent()} para retomar a
+{@link android.content.Intent} que iniciou a atividade. Pode-se fazer isso a qualquer momento durante
+o ciclo de vida da atividade, mas recomenda-se fazê-lo no início do retorno de chamada como
+{@link android.app.Activity#onCreate onCreate()} ou {@link android.app.Activity#onStart()}.</p>
+
+<p>Por exemplo:</p>
+
+<pre>
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.main);
+
+ // Get the intent that started this activity
+ Intent intent = getIntent();
+ Uri data = intent.getData();
+
+ // Figure out what to do based on the intent type
+ if (intent.getType().indexOf("image/") != -1) {
+ // Handle intents with image data ...
+ } else if (intent.getType().equals("text/plain")) {
+ // Handle intents with text ...
+ }
+}
+</pre>
+
+
+<h2 id="ReturnResult">Retornar um resultado</h2>
+
+<p>Se você deseja retornar um resultado para a atividade que invocou a sua, simplesmente chame {@link
+android.app.Activity#setResult(int,Intent) setResult()} para especificar o código do resultado e o resultado {@link
+android.content.Intent}. Quando sua operação estiver concluída e o usuário retornar à atividade
+original, chame {@link android.app.Activity#finish()} para fechar (e destruir) a atividade. Por
+exemplo:</p>
+
+<pre>
+// Create intent to deliver some kind of result data
+Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");
+setResult(Activity.RESULT_OK, result);
+finish();
+</pre>
+
+<p>Sempre especifique um código de resultado com o resultado. Geralmente é {@link
+android.app.Activity#RESULT_OK} ou {@link android.app.Activity#RESULT_CANCELED}. Pode-se fornecer
+dados adicionais com uma {@link android.content.Intent}, caso seja necessário.</p>
+
+<p class="note"><strong>Observação:</strong> o resultado é definido como {@link
+android.app.Activity#RESULT_CANCELED} por padrão. Portanto, se o usuário pressionar o botão <em>Voltar</em>
+antes de concluir a ação e definir o resultado, a atividade original recebe
+o resultado “cancelado”.</p>
+
+<p>Se você apenas precisar retornar um número inteiro que indique uma das várias opções de resultado, defina
+o código de resultados para qualquer valor maior que 0. Se você usar o código do resultado para fornecer um número inteiro e não
+houver necessidade de incluir {@link android.content.Intent}, chame {@link
+android.app.Activity#setResult(int) setResult()} e transmita apenas um código de resultado. Por exemplo:</p>
+
+<pre>
+setResult(RESULT_COLOR_RED);
+finish();
+</pre>
+
+<p>Nesse caso, talvez existam apenas alguns poucos resultados possíveis. Portanto, o código do resultado é um número inteiro definido
+localmente (maior que 0). Isso funciona bem ao retornar um resultado de uma atividade
+em seu próprio aplicativo porque a atividade que recebe o resultado pode fazer uma referência à constante pública
+para determinar o valor do código de resultado.</p>
+
+<p class="note"><strong>Observação:</strong> não há necessidade de verificar se sua atividade foi iniciada
+com {@link
+android.app.Activity#startActivity startActivity()} ou {@link
+android.app.Activity#startActivityForResult startActivityForResult()}. Simplesmente chame {@link
+android.app.Activity#setResult(int,Intent) setResult()} se a intenção que iniciou sua atividade
+estiver esperando um resultado. Se a atividade inicial tivesse chamado {@link
+android.app.Activity#startActivityForResult startActivityForResult()}, o sistema o forneceria
+o resultado para {@link android.app.Activity#setResult(int,Intent) setResult()}. Caso contrário,
+o resultado é ignorado.</p>
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/pt-br/training/basics/intents/index.jd b/docs/html-intl/intl/pt-br/training/basics/intents/index.jd
new file mode 100644
index 0000000..94108b8
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/training/basics/intents/index.jd
@@ -0,0 +1,62 @@
+page.title=Interagindo com outros aplicativos
+page.tags=intenções,atividade
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Dependências e pré-requisitos</h2>
+<ul>
+ <li>Conhecimento básico sobre o ciclo de vida da atividade (consulte <a href="{@docRoot}training/basics/activity-lifecycle/index.html">Como gerenciar o ciclo de vida
+da atividade</a>)</li>
+</ul>
+
+
+<h2>Leia também</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">Compartilhando dados simples</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">Compartilhando arquivos</a>
+ <li><a href="http://android-developers.blogspot.com/2009/11/integrating-application-with-intents.html">
+Integrando aplicativos e intenções (publicações do blog)</a></li>
+ <li><a href="{@docRoot}guide/components/intents-filters.html">Intenções e filtros de
+intenções</a>.</li>
+</ul>
+
+</div>
+</div>
+
+<p>Geralmente, um aplicativo Android tem várias <a href="{@docRoot}guide/components/activities.html">atividades</a>. Cada atividade exibe uma
+interface do usuário que permite ao usuário executar tarefas específicas (como visualizar um mapa ou tirar uma foto).
+Para levar o usuário de uma atividade para outra, o aplicativo deve usar um {@link
+android.content.Intent} para definir a “intenção” do aplicativo de fazer algo. Ao transmitir um
+{@link android.content.Intent} para o sistema com um método como {@link
+android.app.Activity#startActivity startActivity()}, o sistema usa {@link
+android.content.Intent} para identificar e iniciar o componente adequado do aplicativo. Usar intenções
+permite até mesmo que o aplicativo inicie uma atividade que esteja contida em outro aplicativo.</p>
+
+<p>Um {@link android.content.Intent} pode ser <em>explícito</em> para iniciar um componente específico
+(uma instância {@link android.app.Activity} específica) ou <em>implícito</em> para iniciar qualquer
+componente que possa responder à ação pretendida (como “capturar uma foto”).</p>
+
+<p>Esta aula mostra como utilizar um {@link android.content.Intent} para executar algumas interações
+básicas com outros aplicativos, como iniciar outro aplicativo, receber seus resultados, e
+disponibilizar seu aplicativo para responder às intenções de outros aplicativos.</p>
+
+<h2>Lições</h2>
+
+<dl>
+ <dt><b><a href="sending.html">Enviando o usuário para outro aplicativo</a></b></dt>
+ <dd>Mostra como criar intenções implícitas para iniciar outros aplicativos que podem executar uma
+ação.</dd>
+ <dt><b><a href="result.html">Obtendo resultados de uma atividade</a></b></dt>
+ <dd>Como iniciar outra atividade e receber seu resultado.</dd>
+ <dt><b><a href="filters.html">Permitindo que outros aplicativos iniciem sua atividade</a></b></dt>
+ <dd>Como fazer com que atividades em seu aplicativo se abram para serem usadas por outros aplicativos através de definição
+de filtros de intenções que declaram as intenções implícitas aceitas pelo aplicativo.</dd>
+</dl>
+
diff --git a/docs/html-intl/intl/pt-br/training/basics/intents/result.jd b/docs/html-intl/intl/pt-br/training/basics/intents/result.jd
new file mode 100644
index 0000000..ecb5a47
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/training/basics/intents/result.jd
@@ -0,0 +1,178 @@
+page.title=Obtendo resultados de uma atividade
+page.tags=intenções
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>Esta lição ensina a</h2>
+<ol>
+ <li><a href="#StartActivity">Iniciar a atividade</a></li>
+ <li><a href="#ReceiveResult">Receber o resultado</a></li>
+</ol>
+
+<h2>Leia também</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">Compartilhando dados simples</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">Compartilhando arquivos</a>
+</ul>
+
+ </div>
+</div>
+
+<p>Iniciar outra atividade não precisa ser a única forma. Pode-se também iniciar outra atividade e
+receber um resultado de volta. Para receber um resultado, chame {@link android.app.Activity#startActivityForResult
+startActivityForResult()} (em vez de {@link android.app.Activity#startActivity
+startActivity()}).</p>
+
+<p>Por exemplo, o aplicativo pode iniciar um aplicativo de câmera e receber a foto capturada como resultado. Ou,
+ao iniciar o aplicativo Pessoas para que o usuário selecione um
+contato, você receberá os detalhes do contato como resultado.</p>
+
+<p>Evidentemente a atividade que responde deve ser projetada para retornar um resultado. Quando isso acontecer, ela
+enviará o resultado para outro objeto {@link android.content.Intent}. A atividade recebe o resultado no
+retorno de chamada {@link android.app.Activity#onActivityResult onActivityResult()}.</p>
+
+<p class="note"><strong>Observação:</strong> pode-se usar intenções explícitas ou implícitas ao chamar
+{@link android.app.Activity#startActivityForResult startActivityForResult()}. Ao iniciar uma de
+suas próprias atividades que recebem um resultado, use uma intenção explícita para garantir que o
+resultado esperado será recebido.</p>
+
+
+<h2 id="StartActivity">Iniciar a atividade</h2>
+
+<p>Não há nada especial no objeto {@link android.content.Intent} utilizado para iniciar
+uma atividade para um resultado, mas é preciso transmitir um argumento de número inteiro adicional ao método {@link
+android.app.Activity#startActivityForResult startActivityForResult()}.</p>
+
+<p>O argumento de número inteiro é um “código de pedido” que identifica o pedido. Quando você recebe o
+resultado {@link android.content.Intent}, o retorno de chamada fornece o mesmo código de pedido para que o
+aplicativo possa identificar adequadamente o resultado e determinar como responder a ele.</p>
+
+<p>Essa é uma forma de iniciar uma atividade que permite ao usuário escolher um contato:</p>
+
+<pre>
+static final int PICK_CONTACT_REQUEST = 1; // The request code
+...
+private void pickContact() {
+ Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
+ pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
+ startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
+}
+</pre>
+
+
+<h2 id="ReceiveResult">Receber o resultado</h2>
+
+<p>Quando o usuário termina a atividade subsequente e retorna, o sistema chama o método
+{@link android.app.Activity#onActivityResult onActivityResult()} da atividade. Esse método inclui três
+argumentos:</p>
+
+<ul>
+ <li>O código de pedido passado para {@link
+android.app.Activity#startActivityForResult startActivityForResult()}.</li>
+ <li>Um código de resultado especificado pela segunda atividade. Se a operação for bem sucedida, será {@link
+android.app.Activity#RESULT_OK} ou {@link
+android.app.Activity#RESULT_CANCELED} se o usuário tiver desistido ou a operação tiver falhado por algum
+motivo.</li>
+ <li>Um {@link android.content.Intent} que transporta os dados do resultado.</li>
+</ul>
+
+<p>Esta é uma forma de responder ao resultado para a intenção “escolher um contato”:</p>
+
+<pre>
+&#64;Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // Check which request we're responding to
+ if (requestCode == PICK_CONTACT_REQUEST) {
+ // Make sure the request was successful
+ if (resultCode == RESULT_OK) {
+ // The user picked a contact.
+ // The Intent's data Uri identifies which contact was selected.
+
+ // Do something with the contact here (bigger example below)
+ }
+ }
+}
+</pre>
+
+<p>Nesse exemplo, o resultado {@link android.content.Intent} retornado pelos
+aplicativos Contatos ou Pessoas do Android fornece um conteúdo {@link android.net.Uri} que identifica o
+contato escolhido pelo usuário.</p>
+
+<p>Para que o resultado seja tratado de forma adequada, é preciso saber o formato do resultado
+{@link android.content.Intent}. Isso é fácil quando umas das suas atividades
+retorna o resultado. Os aplicativos incluídos na plataforma Android oferecem suas próprias APIs que
+podem ser usadas para dados de resultado específicos. Por exemplo, o aplicativo Pessoas (Contatos em algumas versões mais
+antigas) sempre retorna um resultado com URI de conteúdo que identifica o contato escolhido e o aplicativo
+Câmera retorna um {@link android.graphics.Bitmap} no {@code "data"} extra (consulte a lição
+<a href="{@docRoot}training/camera/index.html">Capturando fotografias</a>).</p>
+
+
+<h4>Bônus: Ler os dados do contato</h4>
+
+<p>O código acima que mostra como obter um resultado pelo aplicativo Pessoas não
+traz muitos detalhes sobre como exatamente ler os dados do resultado porque exige uma discussão mais avançada
+sobre <a href="{@docRoot}guide/topics/providers/content-providers.html">provedores
+de conteúdo</a>. No entanto, se você desejar saber mais, aqui estão alguns códigos que mostram como consultar os
+dados de resultado para obter o número de telefone do contato selecionado:</p>
+
+<pre>
+&#64;Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // Check which request it is that we're responding to
+ if (requestCode == PICK_CONTACT_REQUEST) {
+ // Make sure the request was successful
+ if (resultCode == RESULT_OK) {
+ // Get the URI that points to the selected contact
+ Uri contactUri = data.getData();
+ // We only need the NUMBER column, because there will be only one row in the result
+ String[] projection = {Phone.NUMBER};
+
+ // Perform the query on the contact to get the NUMBER column
+ // We don't need a selection or sort order (there's only one result for the given URI)
+ // CAUTION: The query() method should be called from a separate thread to avoid blocking
+ // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
+ // Consider using {@link android.content.CursorLoader} to perform the query.
+ Cursor cursor = getContentResolver()
+ .query(contactUri, projection, null, null, null);
+ cursor.moveToFirst();
+
+ // Retrieve the phone number from the NUMBER column
+ int column = cursor.getColumnIndex(Phone.NUMBER);
+ String number = cursor.getString(column);
+
+ // Do something with the phone number...
+ }
+ }
+}
+</pre>
+
+<p class="note"><strong>Observação:</strong> antes do Android 2.3 (API nível 9), executar uma consulta
+no {@link android.provider.ContactsContract.Contacts Contacts Provider} (como mostrado
+acima) exige que o aplicativo declare a permissão {@link
+android.Manifest.permission#READ_CONTACTS} (consulte <a href="{@docRoot}guide/topics/security/security.html">Segurança e permissões</a>). Contudo,
+iniciar com Android 2.3, o aplicativo Contatos/Pessoas dá ao aplicativo permissão
+temporária para ler no Provedor de Contatos quando retornar um resultado. A permissão temporária
+aplica-se apenas a pedidos de contato específicos, portanto, não é possível consultar um contato diferente daquele
+especificado pelo {@link android.net.Uri} da intenção, a menos que você declare a permissão {@link
+android.Manifest.permission#READ_CONTACTS}.</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/pt-br/training/basics/intents/sending.jd b/docs/html-intl/intl/pt-br/training/basics/intents/sending.jd
new file mode 100644
index 0000000..526374d
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/training/basics/intents/sending.jd
@@ -0,0 +1,256 @@
+page.title=Enviando o usuário para outro aplicativo
+page.tags=intenções
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>Esta lição ensina a</h2>
+<ol>
+ <li><a href="#Build">Criar uma intenção implícita</a></li>
+ <li><a href="#Verify">Confirmar se há um aplicativo para receber a intenção</a></li>
+ <li><a href="#StartActivity">Iniciar uma atividade com uma intenção</a></li>
+ <li><a href="#AppChooser">Mostrar um selecionador de aplicativo</a></li>
+</ol>
+
+<h2>Leia também</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">Compartilhando dados simples</a></li>
+</ul>
+
+ </div>
+</div>
+
+<p>Uma das características mais importantes do Android é a habilidade do aplicativo enviar o usuário para outro aplicativo
+com base em uma “ação” que gostaria de executar. Por exemplo, se
+o aplicativo tiver o endereço de um negócio que você gostaria de mostrar em um mapa, não é necessário criar
+uma atividade no aplicativo que mostre um mapa. Em vez disso, é possível criar uma solicitação para exibir o endereço
+usando {@link android.content.Intent}. O sistema Android inicia um aplicativo que possa mostrar
+o endereço em um mapa.</p>
+
+<p>Como explicado na primeira lição, <a href="{@docRoot}training/basics/firstapp/index.html">Criando
+seu primeiro aplicativo</a>, use intenções para navegar entre atividades no aplicativo. Geralmente
+isso é feito com <em>intenções explícitas</em>, que define o nome exato da classe do
+componente que deseja iniciar. No entanto, quando desejar que outro aplicativo execute uma ação, como
+“visualizar um mapa”, use uma <em>intenção implícita</em>.</p>
+
+<p>Esta lição mostra como criar uma intenção implícita para uma ação específica e como utilizá-la
+para iniciar uma atividade que executa a ação em outro aplicativo.</p>
+
+
+
+<h2 id="Build">Criar uma intenção implícita</h2>
+
+<p>Intenções implícitas não declaram o nome da classe do componente a iniciar, mas declaram uma
+ação a executar. A ação especifica o que deve ser feito, como <em>visualizar</em>,
+<em>editar</em>, <em>enviar</em> ou <em>obter</em> algo. Geralmente, as intenções incluem dados associados
+à ação, como o endereço que deseja visualizar ou a mensagem de email a ser enviada.
+Dependendo da intenção que deseja criar, os dados podem ser {@link android.net.Uri},
+um dos outros tipos de dados ou a intenção pode não precisar de dado algum.</p>
+
+<p>Se seu dados forem um {@link android.net.Uri}, há um simples construtor {@link
+android.content.Intent#Intent(String,Uri) Intent()} que pode ser usado para definir a ação e
+os dados.</p>
+
+<p>Este é um exemplo de como criar uma intenção para iniciar uma chamada telefônica usando os dados {@link
+android.net.Uri} para especificar o número de telefone:</p>
+
+<pre>
+Uri number = Uri.parse("tel:5551234");
+Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
+</pre>
+
+<p>Quando o aplicativo invoca a intenção chamando {@link android.app.Activity#startActivity
+startActivity()}, o aplicativo Telefone inicia uma chamada para o número especificado.</p>
+
+<p>Estas são algumas outras intenções e suas ações e pares de dados {@link android.net.Uri}
+:</p>
+
+<ul>
+ <li>Visualizar um mapa:
+<pre>
+// Map point based on address
+Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
+// Or map point based on latitude/longitude
+// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
+Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
+</pre>
+ </li>
+ <li>Visualizar uma página da Web:
+<pre>
+Uri webpage = Uri.parse("http://www.android.com");
+Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
+</pre>
+ </li>
+</ul>
+
+<p>Outros tipos de intenções implícitas exigem dados “extras” que fornecem diferentes tipos de dados,
+como uma cadeia de caracteres. É possível adicionar um ou mais dados extras utilizando vários métodos {@link
+android.content.Intent#putExtra(String,String) putExtra()}.</p>
+
+<p>Por padrão, o sistema determina o tipo MIME adequado que uma intenção exige com base nos dados
+{@link android.net.Uri} incluídos. Se você não incluir um {@link android.net.Uri} na
+intenção, sempre utilize {@link android.content.Intent#setType setType()} para especificar o tipo
+de dado associado à intenção. Definir o tipo de MIME especifica melhor que tipos de
+atividades receberão a intenção.</p>
+
+<p>Estas são mais algumas intenções que adicionam dados extra para especificar a intenção desejada:</p>
+
+<ul>
+ <li>Enviar um email com um anexo:
+<pre>
+Intent emailIntent = new Intent(Intent.ACTION_SEND);
+// The intent does not have a URI, so declare the "text/plain" MIME type
+emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
+emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients
+emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
+emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
+emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));
+// You can also attach multiple items by passing an ArrayList of Uris
+</pre>
+ </li>
+ <li>Criar um evento de calendário:
+<pre>
+Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
+Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);
+Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);
+calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
+calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
+calendarIntent.putExtra(Events.TITLE, "Ninja class");
+calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");
+</pre>
+<p class="note"><strong>Observação:</strong> esta intenção para evento de calendário é suportada apenas com nível de API
+14 e superior.</p>
+ </li>
+</ul>
+
+<p class="note"><strong>Observação:</strong> é importante definir seu {@link
+android.content.Intent} para ser o mais específico possível. Por exemplo, se você deseja exibir uma imagem
+usando a intenção {@link android.content.Intent#ACTION_VIEW}, especifique o tipo de MIME do
+{@code image/*}. Isto evita que aplicativos que podem “exibir” outros tipos de dados (como um aplicativo de mapas) seja
+acionado pela intenção.</p>
+
+
+
+<h2 id="Verify">Confirmar se há um aplicativo para receber a intenção</h2>
+
+<p>Embora a plataforma do Android garanta que determinadas intenções sejam resolvidas com um dos
+ aplicativos embutidos (como aplicativo de Telefone, Email ou Agenda), sempre inclua uma
+etapa de confirmação antes de chamar uma intenção.</p>
+
+<p class="caution"><strong>Cuidado:</strong> se você invocar uma intenção e não houver aplicativo
+disponível no dispositivo para tratar a intenção, o aplicativo falhará.</p>
+
+<p>Para confirmar se há atividade disponível para responder à intenção, chame {@link
+android.content.pm.PackageManager#queryIntentActivities queryIntentActivities()} para obter uma lista
+de atividades que podem tratar a {@link android.content.Intent}. Se o {@link
+java.util.List} retornado não estiver vazio, a intenção poderá ser usada com segurança. Por exemplo:</p>
+
+<pre>
+PackageManager packageManager = {@link android.content.Context#getPackageManager()};
+List<ResolveInfo> activities = packageManager.queryIntentActivities(intent,
+ PackageManager.MATCH_DEFAULT_ONLY);
+boolean isIntentSafe = activities.size() > 0;
+</pre>
+
+<p>Se <code>isIntentSafe</code> for <code>true</code>, pelo menos um aplicativo responderá à
+intenção. Se for <code>false</code>, não há aplicativos disponíveis para responder à intenção.</p>
+
+<p class="note"><strong>Observação:</strong> faça essa verificação quando a atividade
+iniciar, caso seja necessário desabilitar a funcionalidade que usa a intenção antes do usuário tentar utilizá-
+la. Caso conheça um aplicativo específico que possa lidar com a intenção, forneça um link para que o
+usuário baixe o aplicativo (veja como <a href="{@docRoot}distribute/tools/promote/linking.html">vincular para seus produtos no Google
+Play</a>).</p>
+
+
+<h2 id="StartActivity">Iniciar uma atividade com uma intenção</h2>
+
+<div class="figure" style="width:200px;margin-top:-10px">
+ <img src="{@docRoot}images/training/basics/intents-choice.png" alt="" />
+ <p class="img-caption"><strong>Figura 1.</strong> Exemplo de diálogo de seleção que aparece
+quando mais de um aplicativo pode tratar uma intenção.</p>
+</div>
+
+<p>Quando tiver criado sua {@link android.content.Intent} e definido as informações extras, chame {@link
+android.app.Activity#startActivity startActivity()} para enviá-la ao sistema. Se o sistema
+identificar mais de uma atividade que pode tratar a intenção, um diálogo exibirá para que o usuário
+selecione qual aplicativo usar, como mostrado na figura 1. Se houver apenas uma atividade para tratar a
+intenção, o sistema a iniciará imediatamente.</p>
+
+<pre>
+startActivity(intent);
+</pre>
+
+<p>Este é um exemplo completo que mostra como criar uma intenção para exibir um mapa, confirmar se há
+um aplicativo para tratar a intenção e iniciar:</p>
+
+<pre>
+// Build the intent
+Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
+Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
+
+// Verify it resolves
+PackageManager packageManager = {@link android.content.Context#getPackageManager()};
+List&lt;ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
+boolean isIntentSafe = activities.size() > 0;
+
+// Start an activity if it's safe
+if (isIntentSafe) {
+ startActivity(mapIntent);
+}
+</pre>
+
+
+
+<h2 id="AppChooser">Mostrar um selecionador de aplicativo</h2>
+
+<div class="figure" style="width:200px;margin-top:-10px">
+ <img src="{@docRoot}images/training/basics/intent-chooser.png" alt="" />
+ <p class="img-caption"><strong>Figura 2.</strong> Um diálogo seletor.</p>
+</div>
+
+<p>Observe que ao iniciar uma atividade passando seu {@link android.content.Intent} para {@link
+android.app.Activity#startActivity startActivity()} e quando há mais de um aplicativo que responde à
+intenção, o usuário pode selecionar qual aplicativo usar por padrão (marcando uma caixa de seleção na parte inferior
+do diálogo, veja a figura 1). Isto é bom quando se executa uma ação para qual o usuário
+deseja usar o mesmo aplicativo todas as vezes, como quando abre uma página da Web (o usuário
+geralmente usa apenas um navegador) ou para tirar fotos (o usuário prefere uma câmera).</p>
+
+<p>Contudo, se a ação a ser executada puder ser tratada por vários aplicativos e o usuário
+preferir um aplicativo diferente a cada vez, como a ação “compartilhar” onde os usuários podem ter vários
+aplicativos para compartilhar um item, você deve exibir explicitamente um diálogo seletor
+conforme mostrado na figura 2. O diálogo seletor
+força o usuário a selecionar qual aplicativo usar para a ação todas as vezes (o usuário não pode selecionar
+um aplicativo padrão para a ação).</p>
+
+<p>Para exibir o seletor, crie uma {@link android.content.Intent} usando {@link
+android.content.Intent#createChooser createChooser()} e transmita para {@link
+android.app.Activity#startActivity startActivity()}. Por exemplo:</p>
+
+<pre>
+Intent intent = 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 chooser
+Intent chooser = Intent.createChooser(intent, title);
+
+// Verify the intent will resolve to at least one activity
+if (intent.resolveActivity(getPackageManager()) != null) {
+ startActivity(chooser);
+}
+</pre>
+
+<p>Isso exibe um diálogo com uma lista de aplicativos que respondem à intenção transmitida ao método {@link
+android.content.Intent#createChooser createChooser()} e utiliza o texto fornecido como
+título do diálogo.</p>
+
+
+
diff --git a/docs/html-intl/intl/ru/design/get-started/principles.jd b/docs/html-intl/intl/ru/design/get-started/principles.jd
new file mode 100644
index 0000000..7f4977c
--- /dev/null
+++ b/docs/html-intl/intl/ru/design/get-started/principles.jd
@@ -0,0 +1,307 @@
+page.title=Принципы проектирования Android
+@jd:body
+
+<p>Эти принципы проектирования были разработаны группой Android
+по взаимодействию приложений с пользователями с целью соблюдения интересов пользователей.
+Для создателей приложений под Android они лежат в
+основе более подробных рекомендаций по проектированию для конкретных
+типов устройств.</p>
+
+<p>
+Учитывайте эти принципы, используя собственный
+творческий потенциал и мышление разработчика. Впрочем, при наличии веских оснований допустимо некоторое отклонение от них.
+</p>
+
+<h2 id="enchant-me">Постарайтесь понравиться пользователю</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="delight-me">Вызовите у пользователя восхищение неожиданными решениями</h4>
+<p>Красивые экраны, тщательно продуманная анимация или своевременные звуковые сигналы создают у пользователя
+хорошее настроение. Утонченные эффекты вызывают у пользователя ощущение,
+что его возможности не ограничены.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_delight.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="real-objects-more-fun">Реальные объекты доставляют больше удовольствия, чем кнопки и меню</h4>
+<p>Позвольте пользователю касаться объектов приложения и манипулировать ими. Это сокращает когнитивные усилия,
+необходимые для выполнения задачи, повышая эмоциональное удовлетворение.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_real_objects.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="make-it-mine">Позвольте пользователю сделать интерфейс индивидуальным</h4>
+<p>Люди любят вносить в интерфейс что-то личное, чтобы чувствовать себя более комфортно и считать, что всё под контролем. Предоставьте
+продуманные и эстетичные настройки по умолчанию и предусмотрите дополнительные настройки, забавные, но не препятствующие
+выполнению основных задач.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_make_it_mine.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="get-to-know-me">Изучите пользователя</h4>
+<p>Постепенно выясняйте предпочтения пользователя Вместо того, чтобы снова и снова заставлять его выбирать одно и то же,
+ сделайте непосредственно доступными ранее выбранные варианты.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_get_to_know_me.png">
+
+ </div>
+</div>
+
+<h2 id="simplify-my-life">Упростите жизнь пользователю</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="keep-it-brief">Будьте лаконичны</h4>
+<p>Используйте короткие фразы с простыми словами. Люди, скорее всего, пропустят длинные предложения.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_keep_it_brief.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="pictures-faster-than-words">Картинки воспринимаются быстрее чем слова</h4>
+<p>Используйте картинки в своих объяснениях. Они завладевают вниманием и действуют гораздо эффективнее
+слов.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_pictures.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="decide-for-me">Принимайте решения за пользователя, но оставляйте последнее слово за ним</h4>
+<p>Не задавайте пользователю лишних вопросов и действуйте наиболее разумным образом. Слишком широкий выбор вызывает чувство
+растерянности. Если существует вероятность, что ваш выбор не устроит пользователя, предоставьте ему возможность отмены.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_decide_for_me.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="only-show-when-i-need-it">Показывайте только самое необходимое и в нужный момент времени</h4>
+<p>Люди не в состоянии справиться сразу с большим количеством информации. Разбивайте задачи и информацию на небольшие легко
+воспринимаемые части. Скройте несущественные на данный момент опции и обучайте пользователя по ходу дела.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_information_when_need_it.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="always-know-where-i-am">Пользователь всегда должен знать, в каком месте приложения он находится</h4>
+<p>Придайте пользователю уверенность, что он не заблудился. Сделайте так, чтобы экраны в вашем приложении отличались друг от друга, и
+используйте переходы, чтобы показать связь между экранами. Обеспечивайте обратную связь от выполняемых задач.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_navigation.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="never-lose-my-stuff">Ни в коем случае не теряйте данные пользователей</h4>
+<p>Сохраняйте данные, на создание которых пользователь потратил свое время, и обеспечьте ему доступ к этой информации из любого места. Запоминайте настройки
+ и предпочтения на телефонах, планшетах и компьютерах. Это позволит значительно упростить
+обновление приложения.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_never_lose_stuff.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="looks-same-should-act-same">Внешне похожие элементы должны вести себя одинаково</h4>
+<p>Помогите людям распознать функциональные различия, сделав их визуально отличимыми.
+Избегайте ситуаций, в которых разные места приложения выглядят похоже, но работают по-разному при одних тех же исходных данных.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_looks_same.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="interrupt-only-if-important">Прерывайте пользователя только в действительно важных ситуациях</h4>
+<p>Подобно хорошему секретарю, приложение должно оградить пользователя от несущественных мелочей. Люди не любят отвлекаться,
+и беспокоить их следует только в исключительно серьезных или не терпящих отлагательства ситуациях.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_important_interruption.png">
+
+ </div>
+</div>
+
+<h2 id="make-me-amazing">Постарайтесь приятно удивить пользователя</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="give-me-tricks">Предоставьте пользователю привычные приемы</h4>
+<p>У людей повышается самооценка, когда они могут разобраться в чем-либо самостоятельно. Сделайте ваше приложение простым в освоении
+за счет использования визуальных моделей и мышечной памяти из других приложений Android. Например, жест скольжения
+является хорошим навигационным приемом.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_tricks.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="its-not-my-fault">Пользователь ни в чем не виноват</h4>
+<p>Будьте корректны, подсказывая пользователю, как выйти из сложного положения. Никто не хочет чувствовать себя бестолковым, имея дело с вашим
+приложением. При возникновении проблем дайте четкие указания по восстановлению, но избавьте пользователя от технических деталей.
+В идеальном варианте приложение способно самостоятельно исправить ситуацию.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_error.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="sprinkle-encouragement">Не скупитесь на поддержку пользователя</h4>
+<p>Разбейте сложные задачи на более мелкие, легко выполнимые этапы. Обеспечьте обратную связь,
+даже при незначительных операциях.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_sprinkle_encouragement.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="do-heavy-lifting-for-me">Выполняйте за пользователя черную работу</h4>
+<p>Дайте новичкам возможность почувствовать себя экспертами, реализовав операции о которых они и не подозревали. Например,
+ярлыки, объединяющие несколько фотоэффектов, позволят превратить любительские фотографии в шедевры всего за
+несколько шагов.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_heavy_lifting.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="make-important-things-fast">Важные действия должны происходить быстро</h4>
+<p>Не все действия равноценны. Решите, какие функции вашего приложения являются самыми важными, и обеспечьте возможность
+быстро найти и использовать их. Например, это может быть кнопка спуска затвора в фотокамере или кнопка паузы в музыкальном плеере.</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_make_important_fast.png">
+
+ </div>
+</div>
diff --git a/docs/html-intl/intl/ru/design/material/index.jd b/docs/html-intl/intl/ru/design/material/index.jd
new file mode 100644
index 0000000..2cfd91e
--- /dev/null
+++ b/docs/html-intl/intl/ru/design/material/index.jd
@@ -0,0 +1,186 @@
+page.title=Material Design
+page.tags=Material Design
+page.type=design
+page.image=design/material/images/MaterialLight.png
+
+@jd:body
+
+<!-- developer docs box -->
+<a class="notice-developers right" href="{@docRoot}training/material/index.html">
+ <div>
+ <h3>Документация для разработчиков</h3>
+ <p>Создание приложений с помощью Material Design</p>
+ </div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw">
+<div>
+ <h3>Видеоролик</h3>
+ <p>Введение в Material Design</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw">
+<div>
+ <h3>Видеоролик</h3>
+ <p>Бумага и чернила: материалы, имеющие первостепенное значение</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc">
+<div>
+ <h3>Видеоролик</h3>
+ <p>Material Design в приложениях для конференции Google I/O</p>
+</div>
+</a>
+
+
+
+<p itemprop="description">Material Design представляет собой комплексную концепцию создания визуальных, движущихся и
+ интерактивных элементов для различных платформ и устройств. Теперь Android включает в себя поддержку
+приложений с элементами Material Design. Чтобы использовать элементы Material Design в своих приложениях под Android, руководствуйтесь инструкциями
+в <a href="http://www.google.com/design/spec">спецификации Material Design</a>, а также воспользуйтесь
+новыми компонентами и функциями, доступными в Android 5.0 (уровень API 21) и выше.</p>
+
+<p>Android предоставляет следующие элементы для построения приложений в соответствии с концепцией Material Design:</p>
+
+<ul>
+ <li>новую тему;</li>
+ <li>новые виджеты для сложных представлений;</li>
+ <li>новые API-интерфейсы для нестандартных теней и анимаций.</li>
+</ul>
+
+<p>Дополнительные сведения о реализации Material Design в Android см. в разделе
+<a href="{@docRoot}training/material/index.html">Создание приложений с помощью Material Design</a>.</p>
+
+
+<h3>Тема Material Design</h3>
+
+<p>Тема Material Design предоставляет новый стиль для ваших приложений, системные виджеты, для которых можно настраивать
+цветовую палитру, и анимации, выполняемые по умолчанию в качестве реакции на касание и при переходах между действиями.</p>
+
+<!-- two columns -->
+<div style="width:700px;margin-top:25px;margin-bottom:20px">
+<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">Тема Material Design в темных тонах</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">Тема Material Design в светлых тонах</p>
+ </div>
+</div>
+<br style="clear:left"/>
+</div>
+
+<p>Дополнительные сведения см. в разделе <a href="{@docRoot}training/material/theme.html">Использование темы
+Material Design</a>.</p>
+
+
+<h3>Списки и подсказки</h3>
+
+<p>Android предоставляет два новых виджета для отображения подсказок и списков с использованием стилей
+и анимаций Material Design:</p>
+
+<!-- two columns -->
+<div style="width:700px;margin-top:25px;margin-bottom:20px">
+<div style="float:left;width:250px;margin-left:40px;margin-right:60px;">
+ <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" />
+ <p>Виджет <code>RecyclerView</code> Представляет собой более гибкую версию <code>ListView</code>,
+которая поддерживает различные типы макетов и способствует повышению производительности.</p>
+</div>
+<div style="float:left;width:250px;margin-right:0px;">
+ <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" />
+ <p>Виджет <code>CardView</code> позволяет отображать важные элементы информации внутри
+ подсказок, имеющие согласованный внешний вид и поведение.</p>
+</div>
+<br style="clear:left"/>
+</div>
+
+<p>Дополнительные сведения см. в разделе <a href="{@docRoot}training/material/lists-cards.html">Создание списков
+и подсказок</a>.</p>
+
+
+<h3>Тени представлений</h3>
+
+<p>Теперь, помимо свойств X и Y, представления в Android имеют свойство
+Z. Это новое свойство показывает, насколько представление "приподнято", иными словами, определяет</p>
+
+<ul>
+<li>размер тени: чем больше Z, тем больше тени, отбрасываемые представлением;</li>
+<li>порядок рисования: представления с более высокими значениями Z отображаются поверх других.</li>
+</ul>
+
+<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/videos/ContactsAnim.webm"/>
+ <source src="{@docRoot}design/videos/ContactsAnim.ogv"/>
+ </video>
+ </div>
+ <div style="font-size:10pt;margin-left:20px;margin-bottom:30px">
+ <em>Для воспроизведения фильма нажмите на экран устройства</em>
+ </div>
+</div>
+
+<p>Дополнительные сведения см. в разделе <a href="{@docRoot}training/material/shadows-clipping.html">Определение
+теней и обрезка представлений</a>.</p>
+
+
+<h3>Анимация</h3>
+
+<p>Новые API-интерфейсы анимации позволяют создавать нестандартную анимацию для реакции на касание в элементах пользовательского интерфейса,
+изменения состояниия представления и переходов между действиями.</p>
+
+<p>Эти API-интерфейсы позволяют</p>
+
+<ul>
+<li style="margin-bottom:15px">
+реагировать на касание в представлениях, используя анимацию для <strong>реакции на касание</strong>;
+</li>
+<li style="margin-bottom:15px">
+скрывать и отображать представление с помощью анимации для <strong>кругового появления</strong>;
+</li>
+<li style="margin-bottom:15px">
+переключаться меду действиями с помощью настраиваемой анимации для <strong>переходов между действиями</strong>;
+</li>
+<li style="margin-bottom:15px">
+создавать более естественное движение с помощью анимации для <strong>перемещения по кривой</strong>;
+</li>
+<li style="margin-bottom:15px">
+анимировать изменение одного или нескольких свойств представления с помощью анимации для <strong>изменения состояния представления</strong>;
+</li>
+<li style="margin-bottom:15px">
+отображать анимацию в <strong>графических элементах списков состояний</strong> в помежутке между изменением состояний представления.
+</li>
+</ul>
+
+<p>Анимация для реакции на касание встроена а некоторые стандартные представления, например, кнопки. Новые API-интерфейсы
+позволяют разработчику настраивать эти анимации и добавлять их в свои нестандартные представления.</p>
+
+<p>Дополнительные сведения, см. в разделе <a href="{@docRoot}training/material/animations.html">Определение настраиваемой
+анимации</a>.</p>
+
+
+<h3>Графические объекты</h3>
+
+<p>Следующие возможности по работе с графическими объектами облегчают реализацию приложений с элементами Material Design:</p>
+
+<ul>
+<li><strong>векторные объекты</strong> можно масштабировать без ущерба для четкости, и они отлично подходят
+в качестве одноцветных значков приложения;</li>
+<li><strong>тонирование графических объектов</strong> позволяет определять растровые изображения как альфа-маску и тонировать их
+нужным цветом во время выполнения;</li>
+<li><strong>извлечение цвета</strong> позволяет автоматически извлекать главные цвета из
+растровых изображений.</li>
+</ul>
+
+<p>Дополнительные сведения см. в разделе <a href="{@docRoot}training/material/drawables.html">Работа с
+элементами дизайна</a>.</p>
diff --git a/docs/html-intl/intl/ru/design/patterns/confirming-acknowledging.jd b/docs/html-intl/intl/ru/design/patterns/confirming-acknowledging.jd
new file mode 100644
index 0000000..99a0d17
--- /dev/null
+++ b/docs/html-intl/intl/ru/design/patterns/confirming-acknowledging.jd
@@ -0,0 +1,70 @@
+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">
+ <img src="{@docRoot}design/media/confirm_ack_confirming.png">
+ <p><strong>Подтверждение</strong> — это просьба к пользователю подтвердить, что он действительно хочет, чтобы запущенное действие было выполнено. Иногда подтверждение отображается вместе с предупреждением или важной информацией относительно действия, которую пользователь должен принять во внимание.</p>
+ </div>
+ <div class="layout-content-col span-6">
+ <img src="{@docRoot}design/media/confirm_ack_acknowledge.png">
+ <p><strong>Уведомление</strong> отображает текст, позволяющий пользователю узнать о завершении действия. Это устраняет неопределенность в отношении неявных операций, которые выполняет система. В некоторых случаях уведомления отображаются вместе с возможностью отменить действие.</p>
+ </div>
+</div>
+
+<p>Взаимодействие с пользователями такими способами позволяет снять неопределенность относительно событий, которые произошли или произойдут. Кроме того, подтверждение или уведомление позволяют удержать пользователя от ошибок, о которых он, возможно, будет сожалеть.</p>
+
+<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">
+ <h4>Пример: Google Play Books</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_books.png">
+ <p>В этом примере пользователь пытается удалить книгу из своей библиотеки Play Google. Для подтверждения этого действия отображается <a href="{@docRoot}design/building-blocks/dialogs.html#alerts">оповещение</a>, поскольку пользователь должен понимать, что книга больше не будет доступна ни с одного устройства.</p>
+ <p>При разработке диалогового окна подтверждения следует создать осмысленный заголовок, отражающий запрошенное действие.</p>
+ </div>
+ <div class="layout-content-col span-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">
+ <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">
+ <h4>Пример: Удаление переписки Gmail</h4>
+ <img src="{@docRoot}design/media/confirm_ack_draft_deleted.png">
+ <p>После того, как пользователь удалит переписку из Gmail, появляется уведомление с возможностью отмены действия. Оно остается, пока пользователь не предпримет постороннее действие, например, прокрутит список писем.</p>
+ </div>
+</div>
+
+<h2>Отсутствие подтверждения или уведомления</h2>
+<div class="layout-content-row">
+ <div class="layout-content-col span-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">
+ <h4>Пример: Удаление приложения с главного экрана</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_removeapp.png">
+ <p><strong>Подтверждение не требуется</strong>. Это преднамеренное действие: пользователь должен перетащить элемент на относительно крупную отдельно расположенную цель. Поэтому случайности здесь практически невероятны. К тому же, если пользователь пожалеет о своем решении, ему потребуется всего несколько секунд, чтобы вернуть приложение.</p>
+ <p><strong>Уведомление не требуется</strong>. Пользователь будет знать, что приложение удалено с главного экрана, потому что сам заставил его исчезнуть в результате перетаскивания.</p>
+
+ </div>
+</div>
diff --git a/docs/html-intl/intl/ru/design/patterns/navigation.jd b/docs/html-intl/intl/ru/design/patterns/navigation.jd
new file mode 100644
index 0000000..a65a8f6
--- /dev/null
+++ b/docs/html-intl/intl/ru/design/patterns/navigation.jd
@@ -0,0 +1,213 @@
+page.title=Навигация с помощью кнопок "Назад" и "Вверх"
+page.tags="navigation","activity","task","up navigation","back navigation"
+page.image=/design/media/navigation_between_siblings_gmail.png
+@jd:body
+
+<a class="notice-developers" href="{@docRoot}training/implementing-navigation/index.html">
+ <div>
+ <h3>Документация для разработчиков</h3>
+ <p>Обеспечение эффективной навигации</p>
+ </div>
+</a>
+
+<p itemprop="description">Внутренне непротиворечивая навигация является важнейшей составляющей пользовательского интерфейса. Мало что так раздражает
+пользователей, как несогласованное или непредсказуемое поведение элементов навигации. В Android 3.0
+глобальное поведение навигации претерпело значительные изменения. Тщательное следование
+инструкциям по применению кнопок "Назад" и "Вверх" сделает навигацию в вашем приложении предсказуемой и надежной с точки зрения пользователей.</p>
+<p>В Android 2.3 и в более ранних версиях для навигации внутри приложения использовалась системная кнопка <em>Назад</em>.
+ С появлением панели действий в Android 3.0 стал доступен второй механизм
+навигации, — кнопка <em>Вверх</em>, содержащая значок приложения и левую угловую скобку.</p>
+
+<img src="{@docRoot}design/media/navigation_with_back_and_up.png">
+
+<h2 id="up-vs-back">Кнопки "Вверх" и "Назад"</h2>
+
+<p>Кнопка "Вверх" используется для навигации внутри приложения по иерархической структуре его
+экранов. Например, если на экране A отображается некоторый список, и при выборе какого-либо элемента открывается
+экран B (с подробной информацией об этом элементе), то на экране B должна присутствовать кнопка "Вверх"
+ для возврата к экрану A.</p>
+<p>Если экран является самым верхним в приложении (то есть главным), он не должен содержать кнопку
+"Вверх".</p>
+
+<p>Системная кнопка "Назад" используется для навигации в обратном хронологическом порядке среди
+экранов, недавно открытых пользователем. Такая навигация основана на порядке появления
+экранов, а не на иерархии приложения.</p>
+
+<p>Если предыдущий экран одновременно является иерархическим родителем текущего,
+кнопка "Назад" имеет то же действие, что и кнопка "Вверх"&mdash;, и это случается довольно
+часто. Однако, в отличие от кнопки "Вверх", гарантирующей, что пользователь остается в приложении, кнопка "Назад"
+может перевести его на главный экран или даже в другое приложение.</p>
+
+<img src="{@docRoot}design/media/navigation_up_vs_back_gmail.png">
+
+<p>Кроме того, кнопка "Назад" проявляет поведение, не связанное напрямую с навигацией между экранами. Она
+</p>
+<ul>
+<li>закрывает перемещаемые окна (диалоговые, всплывающие);</li>
+<li>закрывает контекстные панели действий и снимает выделение с выделенных элементов;</li>
+<li>скрывает экранную клавиатуру (IME).</li>
+</ul>
+<h2 id="within-app">Навигация внутри приложения</h2>
+
+<h4>Переход на экраны с несколькими точками входа</h4>
+<p>Некоторые экраны не имеют строгой позиции в иерархии приложения, и на них можно перейти
+из нескольких точек. Например, на экран настроек можно попасть из любого другого экрана
+приложения. В таком случае кнопка "Вверх" должна осуществлять возврат на вызвавший экран, т. е. вести себя
+идентично кнопке "Назад".</p>
+<h4>Изменение представления содержимого на экране</h4>
+<p>Изменение параметров представления содержимого на экране не сказывается на поведении кнопок "Вверх" и "Назад", — экран остается
+на прежнем месте в иерархии приложения, а история навигации не меняется.</p>
+<p>Примерами изменения представления являются</p>
+<ul>
+<li>переключение представлений с помощью вкладок или жестов прокрутки вправо/влево;</li>
+<li>переключение представлений с помощью раскрывающихся (или свернутых) вкладок;</li>
+<li>фильтрация списка;</li>
+<li>сортировка списка;</li>
+<li>изменение характеристик отображения (например, масштаба).</li>
+</ul>
+<h4>Навигация между экранами одного уровня</h4>
+<p>Когда приложение поддерживает навигацию от списка к подробному представлению одного из его элементов, нередко
+имеет смысл поддержать навигацию от этого элемента к другому, идущему в списке до или
+после него. Например, в Gmail можно провести пальцем влево или вправо по переписке,
+чтобы просмотреть предыдущие или последующие входящие сообщения. Как и в случае изменения представления на экране, такая
+навигация не меняет поведение кнопок "Вверх" и "Назад".</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_gmail.png">
+
+<p>Однако существует важное исключение из этого правила во время просмотра подробных представлений элементов, не связанных
+вместе ссылающимся списком, например&mdash;, приложений
+одного разработчика или альбомов одного исполнителя в Play Store. В этих случаях переход по каждой ссылке создает
+историю навигации, что заставляет кнопку "Назад" перебирать все ранее просмотренные экраны. Кнопка "Вверх" должна по-прежнему
+игнорировать эти связанные по смыслу экраны и осуществлять переход на последний просмотренный контейнерный экран.</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_market1.png">
+
+<p>Разработчик может сделать поведение кнопки "Вверх" еще более интеллектуальным, исходя из своих знаний о структуре подробного
+представления. Вернемся к примеру с просмотром Play Store. Представьте, что пользователь перешел от информации о
+книге к информации о ее экранизации. Тогда кнопка "Вверх" могла бы переводить пользователя в контейнер
+(Фильмы), в котором он еще не был.</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_market2.png">
+
+<h2 id="into-your-app">Навигация внутрь приложения с помощью уведомлений и виджетов главного экрана</h2>
+
+<p>У разработчика также есть возможность использовать уведомления или виджеты главного экрана, чтобы помочь пользователю переходить к экранам,
+расположенным глубоко в иерархической структуре приложения. Например, виджет Inbox приложения Gmail и уведомление о новом сообщении могут
+ перевести пользователя непосредственно к переписке, в обход экрана с входящими сообщениями.</p>
+
+<p>В обоих этих случаях реализуйте следующее поведение кнопки "Вверх":</p>
+
+<ul>
+<li><em>Если целевой экран, как правило, достигается из одного конкретного экрана
+приложения</em>, кнопка "Вверх" должна осуществлять переход на этот экран.</li>
+<li><em>В противном случае</em> кнопка "Вверх" должна осуществлять переход на самый верхний (главный) экран приложения.</li>
+</ul>
+
+<p>Что касается кнопки "Назад", необходимо обеспечить более предсказуемую навигацию, вставив в
+в стек переходов назад полный путь навигации вверх к самому верхнему экрану приложения. Это позволит пользователям,
+забывшим, как они вошли в приложение, перейти к его главному экрану перед выходом из
+приложения.</p>
+
+<p>Например, виджет главного экрана Gmail имеет кнопку, переводящую пользователя прямо на экран
+создания сообщений. Кнопки "Вверх" или "Назад" переведут пользователя с этого экрана на экран входящих писем, а оттуда
+кнопка "Назад" переведет его на главную страницу.</p>
+
+<img src="{@docRoot}design/media/navigation_from_outside_back.png">
+
+<h4>Косвенные уведомления</h4>
+
+<p>Когда приложению нужно вывести информацию сразу о нескольких событиях, оно может выдать
+одно уведомление, направляющее пользователя на промежуточный экран. Этот экран содержит сводку
+событий и предоставляет пользователю возможность перейти вглубь приложения. Такие уведомления
+называются <em>косвенными</em>.</p>
+
+<p>Кнопка "Назад" действует не так, как в случае со стандартными (прямыми) уведомлениями. Нажав ее на промежуточном экране косвенного уведомления,
+пользователь вернется в точку, где было сгенерировано уведомление, &mdash;поскольку
+в стеке переходов назад не появились никакие дополнительные экраны. Если пользователь перейдет в приложение с
+промежуточного экрана, поведение кнопок "Вверх" и "Назад" будет таким же, как и при стандартных уведомлениях:
+навигация внутри приложения, а не возврат к промежуточному экрану.</p>
+
+<p>Например, предположим, что пользователь получил косвенное уведомление от приложения Calendar при открытом приложении Gmail. Если он коснется
+этого уведомления, откроется промежуточный экран с напоминаниями о нескольких
+событиях. Касание кнопки "Назад" на промежуточном экране возвратит пользователя в Gmail. Если пользователь коснется конкретного
+события, он перейдет с промежуточного экрана в приложение Calendar к подробной информации о
+событии. Оттуда кнопки "Вверх" и "Назад" переведут его на верхний уровень приложения Calendar.</p>
+
+<img src="{@docRoot}design/media/navigation_indirect_notification.png">
+
+<h4>Всплывающие уведомления</h4>
+
+<p><em>Всплывающие уведомления</em> появляются непосредственно перед пользователем,
+в обход панели уведомлений. Они используются редко и <strong>должны быть зарезервированы для ситуаций, в которых требуется немедленная
+реакция пользователя, и прерывание его действий оправдано</strong>. Например,
+приложение Talk с помощью таких уведомлений извещает пользователя о поступившем от друга приглашении присоединиться к видеочату, поскольку срок действия этого
+приглашения истекает через несколько секунд.</p>
+
+<p>В отношении навигации всплывающие уведомления ведут себя во многом аналогично промежуточному экрану
+косвенного уведомления. Кнопка "Назад" удаляет всплывающее уведомление. Если пользователь переходит
+от всплывающего уведомления к уведомляющему приложению, кнопки "Вверх" и "Назад" действуют, как при стандартных уведомлениях,
+выполняя навигацию внутри приложения.</p>
+
+<img src="{@docRoot}design/media/navigation_popup_notification.png">
+
+<h2 id="between-apps">Навигация между приложениями</h2>
+
+<p>Одним из фундаментальных достоинств системы Android является способность приложений активировать друг
+друга, что дает пользователю возможность переходить непосредственно из одного приложения в другое. Например,
+приложение, которому нужно сделать снимок, может активировать приложение Camera, которое передаст фотографию
+вызвавшему приложению. Это огромное преимущество, как для разработчика, имеющего возможность без проблем воспользоваться
+кодом других приложений, так и для пользователя, получающего согласованный интерфейс для часто выполняемых
+действий.</p>
+
+<p>Чтобы разобраться в навигации между приложениями, необходимо разобраться в поведении платформы Android,
+которое обсуждается ниже.</p>
+
+<h4>Действия, задачи и намерения</h4>
+
+<p><strong>Действие</strong> в Android — это компонент приложения, определяющий экран с
+информацией и все действия, которые при этом может выполнить пользователь. Приложение представляет собой набор
+действий, состоящий как из действий, созданных разработчиком, так и из тех, которые выполняются с помощью других приложений.</p>
+
+<p><strong>Задача</strong> — последовательность действий, выполняемых пользователем для достижения цели. Отдельная
+задача может использовать действия, заимствованные у одного или у нескольких
+различных приложений.</p>
+
+<p><strong>Намерение</strong> — механизм, позволяющий приложению сигнализировать, что ему требуется помощь
+другого приложения в выполнении некоторого действия. Действия, выполняемые приложением, могут указывать, на какие намерения
+они готовы отвечать. Для осуществления достаточно распространенных намерений, например, "Поделиться", у пользователя может быть установлено несколько приложений,
+ способных выполнить соответствующий запрос.</p>
+
+<h4>Пример: навигация между приложениями для поддержки совместного использования ресурсов</h4>
+
+<p>Чтобы понять, как действия, задачи и намерения взаимодействуют друг с другом, разберемся, как одно приложение позволяет пользователям
+поделиться содержимым с помощью другого приложения. Например, запуск приложения Play Store из главного экрана создает
+новую задачу, Task A (см. рисунок ниже). Когда пользователь выполнит навигацию по Play Store и коснется интересующей его книги,
+чтобы просмотреть информацию о ней, он останется в том же приложении, расширив его возможности с помощью добавленных действий. Запуск
+действия "Поделиться" выводит перед пользователем диалоговое окно со списком действий (из разных приложений),
+зарегистрированных для выполнения намерения "Поделиться".</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_inward.png">
+
+<p>Если пользователь предпочтет поделиться информацией через Gmail, действие "Написать" приложения Gmail добавляется как продолжение задачи
+Task A&mdash;, и никакая новая задача не создается. Если в фоновом режиме работает собственная задача Gmail, на нее это никак
+не повлияет.</p>
+
+<p>Если во время действия "Составление сообщения" пользователь отправит сообщение или коснется кнопки "Назад", он вернется к
+ действию "Просмотр информации о книге". Продолжая нажимать на "Назад", пользователь будет совершать переходы назад в Play
+Store, пока, наконец, не вернется на главный экран.</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_back.png">
+
+<p>Однако, коснувшись кнопки "Вверх" во время действия "Составление сообщения", пользователь выскажет пожелание остаться в приложении
+Gmail. Откроется экран действия "Переписка" приложения Gmail, и для него будет создано новая задача Task B. Новые задачи
+всегда имеют корень на главном экране, поэтому касание кнопки "Назад" на экране переписки возвращает пользователя именно туда.</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_up.png">
+
+<p>Задача Task A остается в фоновом режиме, и пользователь может вернуться к ней впоследствии (например, с помощью
+экрана с последними приложениями). Если в фоновом режиме уже работает собственная задача Gmail, она будет замещена
+задачей Task B. Произойдет отказ от предыдущего контекста ради новой цели пользователя.</p>
+
+<p>Если для обработки намерений ваше приложение зарегистрирует действие, расположенное в глубине своей иерархии,
+следуйте инструкциям по реализации навигации с помощью кнопки "Вверх", изложенным в разделе <a href="#into-your-app">Навигация внутрь приложения с помощью виджетов и
+уведомлений главного экрана</a>.</p>
diff --git a/docs/html-intl/intl/ru/design/patterns/notifications.jd b/docs/html-intl/intl/ru/design/patterns/notifications.jd
new file mode 100644
index 0000000..db46ad5
--- /dev/null
+++ b/docs/html-intl/intl/ru/design/patterns/notifications.jd
@@ -0,0 +1,872 @@
+page.title=Уведомления
+page.tags="notifications","design","L"
+@jd:body
+
+ <a class="notice-developers" href="{@docRoot}training/notify-user/index.html">
+ <div>
+ <h3>Документация для разработчиков</h3>
+ <p>Уведомление пользователя</p>
+ </div>
+</a>
+
+<a class="notice-designers" href="notifications_k.html">
+ <div>
+ <h3>Уведомления в Android версии 4.4 и ниже</h3>
+ </div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=Uiq2kZ2JHVY">
+<div>
+ <h3>Видеоролик</h3>
+ <p>DevBytes: Уведомления в Android L Developer Preview</p>
+</div>
+</a>
+
+<style>
+ .col-5, .col-6, .col-7 {
+ margin-left:0px;
+ }
+</style>
+
+<p>Уведомления позволяют извещать пользователя о релевантных и
+периодически возникающих
+событиях в приложении, таких как новые сообщения в чате или события в календаре.
+Систему уведомлений можно рассматривать как канал новостей, извещающий пользователя о важных
+событиях по мере
+их возникновения, или как журнал, ведущий хронику событий, пока пользователь не обращает на них
+внимания, и синхронизируемый должным образом на всех устройствах Android этого пользователя.</p>
+
+<h4 id="New"><strong>Новые возможности Android 5.0</strong></h4>
+
+<p>В Android 5.0 уведомления были существенно обновлены структурно,
+визуально, и функционально:</p>
+
+<ul>
+ <li>был изменен внешний вид уведомлений в соответствии с новой
+темой Material Design;</li>
+ <li> теперь уведомления доступны на экране блокировки, в то время как
+конфиденциальная информация по-прежнему
+ может быть скрыта;</li>
+ <li>уведомления с высоким приоритетом, полученные при включенном устройстве, теперь имеют новый формат и называются
+ уведомлениями Heads-up;</li>
+ <li>уведомления синхронизируются с облаком: если удалить уведомление на одном из устройств
+Android, оно будет удалено
+ и на остальных устройствах.</li>
+</ul>
+
+<p class="note"><strong>Примечание.</strong> Разработка уведомлений в этой версии
+Android значительно
+отличается от их разработки в предыдущих версиях. Информацию о разработке уведомлений в предыдущих
+версиях можно найти в разделе <a href="./notifications_k.html">Уведомления в Android версии 4.4 и ниже</a>.</p>
+
+<h2 id="Anatomy">Структура уведомления</h2>
+
+<p>В этом разделе описываются основные компоненты уведомления и их
+отображение на устройствах различных типов.</p>
+
+<h3 id="BaseLayout">Базовая компоновка</h3>
+
+<p>Все уведомления имеют, как минимум, базовую компоновку, которую составляют следующие элементы.</p>
+
+<ul>
+ <li> <strong>Значок</strong> уведомления. Значок символизирует
+инициирующее приложение. Он также может
+ указывать на тип уведомления, если приложение генерирует уведомления нескольких
+типов.</li>
+ <li> <strong>Заголовок</strong> уведомления и дополнительный
+<strong>текст</strong>.</li>
+ <li> <strong>Временная метка</strong>.</li>
+</ul>
+
+<p>Уведомления, созданные с помощью {@link android.app.Notification.Builder Notification.Builder}
+для предыдущих версий платформы, выглядят и функционируют в Android
+5.0 так же, как и прежде, за исключением незначительных стилистических отличий, вносимых
+системой. Дополнительную информацию о внешнем виде и функциональности уведомлений в предыдущих версиях
+Android можно найти в разделе
+<a href="./notifications_k.html">Уведомления в Android версии 4.4 и ниже</a>.</p></p>
+
+
+ <img style="margin:20px 0 0 0" src="{@docRoot}images/android-5.0/notifications/basic_combo.png" alt="" width="700px" />
+
+
+<div style="clear:both;margin-top:20px">
+ <p class="img-caption">
+ Уведомление в базовой компоновке на мобильном устройстве (слева) и то же уведомление на носимом устройстве (справа)
+ с фотографией пользователя и значком уведомления
+ </p>
+ </div>
+
+<h3 id="ExpandedLayouts">Расширенная компоновка</h3>
+
+
+<p>Разработчик может выбрать степень подробности уведомлений, генерируемых его
+приложением. Уведомление может содержать первые
+несколько строк сообщения или миниатюру изображения. В качестве дополнительной
+информации можно предоставлять пользователю
+контекст и, &mdash;в некоторых случаях, &mdash;давать ему возможность прочитать сообщение
+целиком. Чтобы переключаться
+ между компактной и расширенной компоновкой, пользователь может применить жест сжатия/масштабирования или
+провести пальцем по экрану.
+ Для уведомлений о единичных событиях Android предоставляет
+ разработчику приложения три шаблона расширенной компоновки
+(текст, входящая почта и изображения). Ниже приведены скриншоты уведомлений о единичных
+событиях на мобильных устройствах (слева)
+ и на носимых устройствах (справа).</p>
+
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/expandedtext_combo.png"
+ alt="" width="700px" height;="284px" />
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/stack_combo.png"
+ alt="" width="700px" height;="284px" />
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/ExpandedImage.png"
+ alt="" width="311px" height;="450px" />
+
+<h3 id="actions" style="clear:both; margin-top:40px">Действия</h3>
+
+<p>Android поддерживает дополнительные действия, отображаемые в нижней части
+уведомления.
+Благодаря этому пользователи могут выполнять операции, типичные для данного
+уведомления, непосредственно из него, не открывая
+само приложение.
+Это ускоряет взаимодействие и, вместе с операцией "провести пальцем, чтобы удалить", позволяет пользователю сосредоточиться на
+важных для него уведомлениях.</p>
+
+
+ <img src="{@docRoot}images/android-5.0/notifications/action_combo.png" alt="" width="700px" />
+
+
+
+<p style="clear:both">При определении количества действий в уведомлении следует проявлять
+благоразумие. Чем больше
+действий предоставлено пользователю, тем выше когнитивная сложность приложения. Ограничьтесь
+минимальным количеством
+действий, предоставив пользователю наиболее важные и
+значимые.</p>
+
+<p>В уведомлениях отдавайте предпочтение действиям</p>
+
+<ul>
+ <li> важным, выполняемым наиболее часто и типичным для отображаемого
+содержимого;
+ <li> позволяющим пользователю быстрее решить задачу.
+</ul>
+
+<p>Избегайте действий</p>
+
+<ul>
+ <li> неоднозначных;
+ <li> совпадающих с действиями, выполняемыми для данного уведомления по умолчанию (например, "Прочитать" или
+"Открыть").
+</ul>
+
+
+
+<p>Следует предоставлять не более трех действий, указав для каждого
+значок и название.
+ Добавление действий в базовую компоновку делает уведомление расширяемым,
+даже если
+ оно не имеет расширенной компоновки. Поскольку действия отображаются только у
+расширенных
+ уведомлений, необходимо, чтобы любое действие,
+которое пользователь может выполнить из
+ уведомления, было доступно и в соответствующем
+приложении.</p>
+
+<h2 style="clear:left">Уведомления heads-up</h2>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/hun-example.png" alt="" width="311px" />
+ <p class="img-caption">
+ Пример уведомления heads-up (входящий телефонный звонок, высокий приоритет),
+появляющегося поверх
+ приложения с эффектом присутствия
+ </p>
+</div>
+
+<p>Когда поступает уведомление с высоким приоритетом (см. изображение справа), оно в течение короткого времени
+отображается
+в расширенной компоновке, позволяя выполнить допустимые действия.</p>
+<p> Затем уведомление принимает обычный
+вид. Если для уведомления установлен высокий, максимальный или полноэкранный <a href="#correctly_set_and_manage_notification_priority">приоритет</a>
+, оно становится уведомлением heads-up.</p>
+
+<p><b>Хорошими примерами событий для уведомлений heads-up являются</b></p>
+
+<ul>
+ <li> входящий телефонный звонок, во время использования устройства;</li>
+ <li> сигнал будильника во время использования устройства;</li>
+ <li> новое SMS-сообщение;</li>
+ <li> низкий уровень заряда аккумулятора.</li>
+</ul>
+
+<h2 style="clear:both" id="guidelines">Основные рекомендации</h2>
+
+
+<h3 id="MakeItPersonal">Персонализируете уведомление</h3>
+
+<p>Уведомление о событии, инициированном другим пользователем (например, сообщение или
+обновление статуса), должно содержать изображение пользователя, добавленное с помощью
+{@link android.app.Notification.Builder#setLargeIcon setLargeIcon()}. Кроме того, в метаданные уведомления необходимо включить информацию о
+пользователе (см. {@link android.app.Notification#EXTRA_PEOPLE}).</p>
+
+<p>Главный значок уведомления будет по-прежнему отображаться, чтобы пользователь мог связать
+его со значком
+на строке состояния.</p>
+
+
+<img src="{@docRoot}images/android-5.0/notifications/Triggered.png" alt="" width="311px" />
+<p style="margin-top:10px" class="img-caption">
+ Уведомление, идентифицирующее пользователя-инициатора, и отображающее отправленное содержимое.
+</p>
+
+
+<h3 id="navigate_to_the_right_place">Выполняйте переход в нужное место</h3>
+
+<p>Когда пользователь касается тела уведомления (за пределами кнопок
+с действиями), должен осуществляться переход в то место приложения,
+где пользователь сможет просмотреть информацию, о которой извещает уведомление, и действовать в соответствии
+с нею. В большинстве случаев там будет находиться подробное представление одного элемента данных, например, сообщения,
+но возможно и
+сокращенное представление, если накопилось несколько уведомлений. Если приложение переводит
+пользователя на какой-либо уровень, отличный от верхнего, реализуйте навигацию в стеке переходов назад в приложении, чтобы
+пользователь мог нажать системную кнопку "Назад" и вернуться на верхний уровень. Дополнительную информацию можно найти в разделе
+<em>Навигация внутрь приложения с помощью виджетов и уведомлений главного экрана</em> в шаблоне проектирования
+<a href="{@docRoot}design/patterns/navigation.html#into-your-app">Навигация</a>.</p>
+
+<h3 id="correctly_set_and_manage_notification_priority">Правильно выполняйте расстановку приоритетов уведомлений и
+управление ими
+</h3>
+
+<p>Android поддерживает флаг приоритета для уведомлений. Это флаг позволяет
+влиять на позицию уведомления среди других уведомлений и
+гарантировать,
+что пользователь в первую очередь увидит самые важные уведомления. При отправке уведомления можно выбрать один
+из
+следующих уровней приоритета:</p>
+<table>
+ <tr>
+ <td class="tab0">
+<p><strong>Приоритет</strong></p>
+</td>
+ <td class="tab0">
+<p><strong>Использование</strong></p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>MAX</code></p>
+</td>
+ <td class="tab1">
+<p>Применяйте для наиболее важных и неотложных уведомлений, извещающих пользователя
+о ситуации,
+критичной по времени или такой, на которую необходимо отреагировать, чтобы продолжить
+выполнение задачи.</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>HIGH</code></p>
+</td>
+ <td class="tab1">
+<p>Применяйте, в основном, для передачи важной информации, например, о сообщениях или событиях
+в чате с содержимым, представляющим особый интерес для пользователя.
+Уведомления с высоким приоритетом отображаются как уведомления heads-up.</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>DEFAULT</code></p>
+</td>
+ <td class="tab1">
+<p>Применяйте для всех уведомлений, не входящих ни в одну из описанных здесь категорий.</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>LOW</code></p>
+</td>
+ <td class="tab1">
+<p>Применяйте для уведомлений, которые должны быть переданы пользователю, но
+не являются неотложными. Низкоприоритетные уведомления обычно появляются в конце списка,
+что позволяет использовать их
+для передачи информации, представляющей всеобщий интерес и не имеющей конкретной направленности. Например, если пользователь подписался
+на новости,
+ эта информация не должна иметь преимущество перед неотложными или адресными
+сообщениями.</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>MIN</code></p>
+</td>
+ <td class="tab1">
+<p>Применяйте для уведомлений, с контекстной или фоновой информацией, такой как прогноз погоды, или с информацией,
+связанной с местоположением пользователя.
+Уведомления с минимальным приоритетом не отображаются в строке состояния. Пользователь
+обнаруживает их при раскрытии панели уведомления.</p>
+</td>
+ </tr>
+</table>
+
+
+<h4 id="how_to_choose_an_appropriate_priority"><strong>Как выбрать
+подходящий
+приоритет</strong></h4>
+
+<p>При выдаче уведомлений с приоритетами <code>DEFAULT</code>, <code>HIGH</code> и <code>MAX</code> существует риск, что деятельность
+пользователя будет прервана
+в самом разгаре. Чтобы не раздражать пользователей вашего приложения, применяйте приоритеты этих уровней для
+уведомлений,</p>
+
+<ul>
+ <li> имеющих отношение к другим пользователям;</li>
+ <li> быстро теряющих актуальность;</li>
+ <li> способных немедленно повлиять на поведение пользователя в реальном мире.</li>
+</ul>
+
+<p>Уведомления с приоритетом <code>LOW</code> и <code>MIN</code> могут представлять определенную ценность
+для пользователя. Значительное количество, если не большинство, уведомлений не требует немедленной
+реакции пользователя, но, тем не менее, содержит информацию, которую пользователь сочтет
+ценной, когда решит
+просмотреть поступившие уведомления. Приоритеты уровней <code>LOW</code> и <code>MIN</code>
+ следует присваивать уведомлениям,</p>
+
+<ul>
+ <li> не имеющим прямого отношения к другим пользователям;</li>
+ <li> долго не теряющим актуальность;</li>
+ <li> содержащим информацию, способную заинтересовать пользователя, если он решит
+просмотреть их в свободное время.</li>
+</ul>
+
+
+ <img src="{@docRoot}images/android-5.0/notifications/notifications_pattern_priority.png" alt="" width="700" />
+
+
+<h3 style="clear:both" id="set_a_notification_category">Определите категорию
+уведомления</h3>
+
+<p>Если уведомление попадает в одну из заранее определенных категорий (см.
+ниже), укажите его
+категорию. Процессы системного пользовательского интерфейса, например, панель уведомления (или любой
+другой процесс-слушатель
+уведомлений) могут воспользоваться этой информацией при классификации и фильтрации уведомлений.</p>
+<table>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_CALL">CATEGORY_CALL</a></code></p>
+</td>
+ <td>
+<p>Входящий звонок (голосовой или по видеосвязи) или алогичный запрос синхронной
+связи</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_MESSAGE">CATEGORY_MESSAGE</a></code></p>
+</td>
+ <td>
+<p>Входящее личное сообщение (SMS-сообщение, мгновенное сообщение и т. д.)</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_EMAIL">CATEGORY_EMAIL</a></code></p>
+</td>
+ <td>
+<p>Асинхронное массовое сообщение (по электронной почте)</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_EVENT">CATEGORY_EVENT</a></code></p>
+</td>
+ <td>
+<p>Событие в календаре</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_PROMO">CATEGORY_PROMO</a></code></p>
+</td>
+ <td>
+<p>Промоакция или реклама</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_ALARM">CATEGORY_ALARM</a></code></p>
+</td>
+ <td>
+<p>Сигнал будильника или таймера</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_PROGRESS">CATEGORY_PROGRESS</a></code></p>
+</td>
+ <td>
+<p>Информация о ходе выполнения длительной фоновой операции</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SOCIAL">CATEGORY_SOCIAL</a></code></p>
+</td>
+ <td>
+<p>Новости, поступившие из социальной сети или касающиеся совместного использования ресурсов</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_ERROR">CATEGORY_ERROR</a></code></p>
+</td>
+ <td>
+<p>Ошибка в фоновой операции или статусе аутентификации</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_TRANSPORT">CATEGORY_TRANSPORT</a></code></p>
+</td>
+ <td>
+<p>Управление передачей медиаданных для воспроизведения</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SYSTEM">CATEGORY_SYSTEM</a></code></p>
+</td>
+ <td>
+<p>Обновление статуса системы или устройства. Зарезервировано для использования системой.</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SERVICE">CATEGORY_SERVICE</a></code></p>
+</td>
+ <td>
+<p>Индикация работающей фоновой службы</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_RECOMMENDATION">CATEGORY_RECOMMENDATION</a></code></p>
+</td>
+ <td>
+<p>Конкретная и привязанная ко времени рекомендация относительно одного объекта. Например, приложение
+новостей может
+порекомендовать пользователю, какую новость читать следующей.</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_STATUS">CATEGORY_STATUS</a></code></p>
+</td>
+ <td>
+<p>Текущая информация о статусе устройства или контекста</p>
+</td>
+ </tr>
+</table>
+
+<h3 id="summarize_your_notifications">Суммируйте уведомления</h3>
+
+<p>Если при наличии ожидающего уведомления определенного типа приложение пытается отправить новое
+уведомление того же типа, объедините их в одно сводное уведомление от этого приложения. Не
+создавайте новый объект.</p>
+
+<p>Сводное уведомление формирует сводное описание и дает пользователю возможность
+понять, сколько
+имеется ожидающих уведомлений того или иного типа.</p>
+
+<div class="col-6">
+
+<p><strong>Неправильно</strong></p>
+ <img src="{@docRoot}images/android-5.0/notifications/Summarise_Dont.png" alt="" width="311px" />
+</div>
+
+<div>
+<p><strong>Правильно</strong></p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/Summarise_Do.png" alt="" width="311px" />
+</div>
+
+<p style="clear:left; padding-top:30px; padding-bottom:20px">Разработчик может сообщить
+подробности об отдельных уведомлениях, образующих
+ сводное, используя расширенную компоновку для резюме. Такой подход позволит пользователям
+лучше разобраться, какие
+уведомления ожидают прочтения, и достаточно ли они интересны, чтобы ознакомиться с ними
+более подробно в
+ соответствующем приложении.</p>
+<div class="col-6">
+ <img src="{@docRoot}images/android-5.0/notifications/Stack.png" style="margin-bottom:20px" alt="" width="311px" />
+ <p class="img-caption">
+ Расширенное и сжатое сводное уведомление (с использованием <code>InboxStyle</code>)
+ </p>
+</div>
+
+<h3 style="clear:both" id="make_notifications_optional">Сделайте уведомления
+необязательными</h3>
+
+<p>В распоряжении пользователей всегда должен быть метод управления уведомлениями. Предоставьте пользователю возможность
+отключать уведомления, поступающие от вашего приложения,
+или изменять способы оповещения, такие как звуковой сигнал и
+вибрация.
+ С этой целью следует предусмотреть пункт настройки уведомлений в настройках приложения.</p>
+
+<h3 id="use_distinct_icons">Используйте отчетливые значки</h3>
+<p>Беглого взгляда на область уведомлений должно быть достаточно, чтобы распознать
+типы
+ожидающих уведомлений.</p>
+
+<div class="figure">
+ <img src="{@docRoot}images/android-5.0/notifications/ProductIcons.png" alt="" width="420" />
+</div>
+
+ <div><p><strong>Правильно</strong></p>
+ <p>Рассмотрите уже существующие значки уведомлений от приложений Android и создайте
+собственные,
+ достаточно уникальные.</p>
+
+ <p><strong>Правильно</strong></p>
+ <p>Придерживайтесь подходящего <a href="/design/style/iconography.html#notification">стиля значков уведомления</a>
+ для мелких значков, и
+ <a href="/design/style/iconography.html#action-bar">стиля строки
+действий</a> Material Light для значков
+ действий.</p>
+<p ><strong>Правильно</strong></p>
+<p >Стремитесь к визуальной простоте значков, избегайте излишних трудноразличимых
+деталей.</p>
+
+ <div><p><strong>Неправильно</strong></p>
+ <p>Применяйте к мелким значкам и значкам действий дополнительные альфа-эффекты
+(постепенное появление/исчезание).
+ К их краям может быть применено сглаживание, но, поскольку в Android эти значки
+служат масками (то есть,
+ используется только альфа-канал), изображение, как правило, должно отображаться полностью
+непрозрачным.</p>
+
+</div>
+<p style="clear:both"><strong>Неправильно</strong></p>
+
+<p>Чтобы ваше приложение отличалось от других, используйте цвет. Значки уведомлений должны
+представлять собой изображение белого цвета на прозрачном фоне.</p>
+
+
+<h3 id="pulse_the_notification_led_appropriately">Правильно используйте индикатор
+уведомлений</h3>
+
+<p>На многих устройствах Android имеется светодиодный индикатор уведомлений,
+информирующий пользователя о
+событиях, когда экран выключен. Уведомления с приоритетом <code>MAX</code>,
+<code>HIGH</code> или <code>DEFAULT</code> должны
+вызывать свечение индикатора, а уведомления с низким приоритетом (<code>LOW</code> и
+<code>MIN</code>) не должны.</p>
+
+<p>Возможности пользователя управлять уведомлениями должны распространяться на светодиодный индикатор. Когда разработчик использует
+DEFAULT_LIGHTS,
+индикатор светится белым цветом. Ваши уведомления не должны вызывать свечение другим
+цветом, если
+пользователь не указал этого явным образом.</p>
+
+<h2 id="building_notifications_that_users_care_about">Создание уведомлений,
+ важных для пользователя</h2>
+
+<p>Чтобы пользователям понравилось ваше приложение, необходимо тщательно
+продумать его уведомления.
+Уведомления — это голос приложения. Они определяют его
+индивидуальность. Ненужные или
+несущественные уведомления раздражают пользователя и заставляют его возмущаться тем, как много
+внимания требует от него
+приложение. Поэтому необходимо применять уведомления взвешенно.</p>
+
+<h3 id="when_to_display_a_notification">Ситуации, в которых следует показывать уведомления</h3>
+
+<p>Чтобы создать приложение, от работы с которым пользователи получат удовольствие, необходимо
+осознать, что внимание пользователя
+ является ресурсом, требующим бережного обращения. Система уведомлений
+Android была разработана
+так, чтобы как можно меньше отвлекать пользователя.
+Однако
+вы должны отдавать себе отчет в том, что уведомления прерывают
+деятельность пользователя.
+Планируя уведомления, спрашивайте себя, достаточно ли они важны, чтобы
+послужить основанием для такого прерывания. В случае сомнений предоставьте пользователю возможность запросить
+в настройках приложения получение уведомления или измените
+приоритет уведомления на <code>LOW</code> или <code>MIN</code>, чтобы
+не отвлекать пользователя от
+текущих занятий.</p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/TimeSensitive.png" alt="" width="311px" />
+ <p style="margin-top:10px" class="img-caption">
+ Примеры уведомлений, быстро теряющих актуальность
+ </p>
+
+<p>Хотя правильно работающие приложения ведут себя неназойливо, бывают ситуации,
+заслуживающие того, чтобы приложение по своей инициативе прервало деятельность пользователя уведомлением.</p>
+
+<p>Отправляйте уведомления только в случае <strong>событий, требующих неотложной реакции</strong>, особенно
+ если эти синхронные события <strong>имеют прямое отношение к другим пользователям</strong>. Например,
+чат
+ представляет собой форму синхронного общения в реальном времени, — другой пользователь
+с нетерпением ожидает вашего ответа. События в календаре являются еще одним хорошим примером ситуации, в которой следует выдать
+уведомление и завладеть
+ вниманием пользователя, потому что в приближающееся календарное событие часто
+вовлечены другие люди.</p>
+
+<h3 style="clear:both" id="when_not_to_display_a_notification">Ситуации,
+в которых не следует показывать уведомления</h3>
+
+<div class="figure" style="margin-top:60px">
+ <img src="{@docRoot}images/android-5.0/notifications/AntiSample1.png" alt="" width="311px" />
+</div>
+
+<p>В большинстве остальных случаев уведомления неуместны.</p>
+
+<ul>
+ <li> Не следует извещать пользователя о событиях, не имеющих отношения
+к нему конкретно, или
+ не теряющих актуальность со временем. Например, асинхронные
+и безадресные новости,
+ циркулирующие в социальных сетях, как правило, не требуют немедленного
+привлечения внимания. Пользователям,
+ действительно интересующимся таким новостями, предоставьте возможность запросить соответствующие уведомления.</li>
+ <li> Не генерируйте уведомление, если релевантная свежая информация уже находится
+на экране. Вместо этого
+ воспользуйтесь интерфейсом самого приложения, чтобы донести до пользователя новую информацию
+непосредственно в контексте.
+ Например, приложение-чат не должно генерировать системные уведомления,
+пока пользователь активно общается с собеседником.</li>
+ <li> Не отвлекайте пользователя ради низкоуровневых технических действий, такие как сохранение
+или синхронизация информации или обновление приложения, если приложение или система способны выполнить задачу
+без вмешательства пользователя.</li>
+ <li> Не отвлекайте пользователя, чтобы проинформировать его об ошибке, если
+приложение может восстановиться после нее самостоятельно, не требуя от пользователя
+никаких действий.</li>
+ <li> Не создавайте уведомления, не имеющие осмысленного содержимого и
+всего лишь рекламирующие ваше
+приложение. Уведомление должно нести полезную, актуальную и новую информацию. Не следует
+использовать его
+ исключительно для презентации приложения.</li>
+ <li> Не создавайте избыточные уведомления только для того, чтобы продемонстрировать свой бренд
+пользователям.
+ Такие уведомления раздражают и отталкивают аудиторию. Лучший
+способ сообщать
+ новую информацию небольшими порциями и поддерживать связь пользователей
+с вашим
+ приложением заключается в том, чтобы разработать виджет, который они смогут поместить на
+ главный экран.</li>
+</ul>
+
+<h2 style="clear:left" id="interacting_with_notifications">Взаимодействие с
+уведомлениями</h2>
+
+<p>Уведомления обозначаются значками в строке состояния. Чтобы получить к ним доступ,
+следует открыть
+панель уведомлений.</p>
+
+<p>Если коснуться уведомления, откроется соответствующее приложение с подробным содержимым,
+связанным с эти уведомлением.
+Если провести пальцем по уведомлению влево или вправо, оно будет удалено из панели.</p>
+
+<h3 id="ongoing_notifications">Постоянные уведомления</h3>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/MusicPlayback.png" alt="" width="311px" />
+ <p class="img-caption">
+ Постоянные уведомления при воспроизведении музыки
+ </p>
+</div>
+<p>Постоянные уведомления информируют пользователя о текущих фоновых
+процессах.
+Например, плееры сообщают через систему уведомлений информацию о дорожке,
+воспроизводимой в данный момент, и
+это продолжается, пока пользователь не остановит воспроизведение. Кроме того, постоянные уведомления могут
+информировать пользователя
+о ходе выполнения длительных задач, таких как загрузка файла или кодирование видеоданных. Пользователь не может вручную
+удалить постоянное уведомление из панели уведомлений.</p>
+
+<h3 id="ongoing_notifications">Воспроизведение медиаданных</h3>
+<p>В Android 5.0 на экране блокировки не отображаются элементы управления воспроизведением от устаревшего
+класса {@link android.media.RemoteControlClient}. Однако на нем <em>отображаются</em> уведомления, так что теперь каждое
+уведомление приложения о воспроизведении является для пользователей основным
+способом управления воспроизведением в заблокированном состоянии. В результате у приложения появляется больше возможностей
+управлять тем, какие
+кнопки отображать, и каким образом. При этом с точки зрения пользователя система ведет себя непротиворечиво,
+независимо от того, заблокирован ли экран.</p>
+
+<h3 style="clear:both"
+id="dialogs_and_toasts_are_for_feedback_not_notification">Диалоговые окна
+и всплывающие уведомления</h3>
+
+<p>Приложение, не отображаемое на экране, не должно генерировать диалоговое окно или всплывающее
+уведомление. Диалоговое окно или всплывающее уведомление
+ должно появляться исключительно в качестве немедленной реакции на действия пользователя
+в приложении.
+Более подробные рекомендации по использованию диалоговых окон и всплывающих уведомлений см. в разделе
+<a href="/design/patterns/confirming-acknowledging.html">Подтверждение и уведомление</a>.</p>
+
+<h3>Упорядочение уведомлений по степени важности</h3>
+
+<p>По своей сути уведомления — это новости, и поэтому они принципиально отображаются в
+обратном хронологическом порядке.
+При этом обязательно принимается во внимание
+<a href="#correctly_set_and_manage_notification_priority">приоритет</a>, установленный приложением.</p>
+
+<p>Уведомления являются важной составляющей экрана блокировки и отображаются на видном месте
+каждый
+раз, когда включается дисплей устройства. На экране блокировки мало свободного места, поэтому
+исключительно важно
+выявлять неотложные или наиболее релевантные уведомления. По этой
+причине Android применяет
+сложный алгоритм сортировки уведомлений, в котором учитываются</p>
+
+<ul>
+ <li> временная метка и приоритет, установленный приложением;</li>
+ <li> тот факт, что уведомление только что оповестило пользователя звуковым сигналом
+или вибрацией (иными словами,
+ если телефон издает звуки, и пользователь хочет узнать, в чем
+дело, то на экране блокировки
+ должен находиться ответ, понятный с первого взгляда);</li>
+ <li> пользователи, связанные с уведомлением при помощи {@link android.app.Notification#EXTRA_PEOPLE},
+ и, в частности, присутствие их в списке помеченных контактов.</li>
+</ul>
+
+<p>Чтобы воспользоваться преимуществами этой сортировки наилучшим образом, думайте в первую очередь о создании
+удобных условий для
+пользователя, и не нацеливайтесь на конкретное место в рейтинге.</p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/AntiSample3.png" alt="" width="700px" />
+
+ <p class="img-caption" style="margin-top:10px">Уведомления от Gmail имеют
+приоритет DEFAULT, поэтому они
+ обычно оказываются ниже уведомлений от приложений мгновенного обмена сообщениями, таких как Hangouts, но
+поднимаются в списке
+ на некоторое время, когда поступают новые сообщения.
+ </p>
+
+
+<h3>Уведомления на экране блокировки</h3>
+
+<p>Поскольку уведомления видны на экране блокировки, защита конфиденциальной информации пользователей приобретает
+особо
+важное значение. Уведомления нередко содержат частную информацию, и они
+не должны быть доступны
+каждому, кто взял в руки устройство и включил дисплей.</p>
+
+<ul>
+ <li> У устройств, экран блокировки которых защищен (при помощи PIN-кода, графического ключа или пароля), интерфейс имеет
+ общедоступную и закрытую части. Элементы общедоступного интерфейса отображаются на защищенном экране блокировки и
+ следовательно, видны всем. Закрытый интерфейс находится "позади" экрана блокировки и
+ доступен только пользователю, выполнившему вход в устройство.</li>
+</ul>
+
+<h3>Возможности пользователя контролировать информацию, отображаемую на экране блокировки</h3>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/LockScreen@2x.png" srcset="{@docRoot}images/android-5.0/notifications/LockScreen.png 1x" alt="" width="311px" />
+ <p class="img-caption">
+ Уведомления на экране блокировки с содержимым, отображаемым после того, как пользователь разблокирует устройство.
+ </p>
+</div>
+
+<p>При настройке защиты экрана блокировки пользователь может предпочесть,
+ чтобы конфиденциальные данные не отображались на защищенном экране блокировки. В этом случае системный пользовательский интерфейс
+учитывает <em>уровень видимости</em> уведомления, чтобы выяснить, какую информацию
+можно отображать без риска.</p>
+<p> Чтобы установить уровень видимости, вызовите
+<code><a
+href="/reference/android/app/Notification.Builder.html#setVisibility(int)">Notification.Builder.setVisibility()</a></code>
+и укажите одно из следующих значений:</p>
+
+<ul>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_PUBLIC">VISIBILITY_PUBLIC</a></code>.
+Содержимое уведомления отображается полностью.
+ Это значение принимается системой по умолчанию, если уровень видимости не указан.</li>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_PRIVATE">VISIBILITY_PRIVATE</a></code>.
+На экране блокировки отображается основная информация о наличии уведомления, включая его
+значок и название приложения, отправившего его. Прочие данные уведомления скрыты.
+Здесь уместно дать разработчику пару рекомендаций.
+ <ul>
+ <li> Если вы хотите реализовать отдельную общедоступную версию уведомления,
+которую система будет отображать на экране блокировки, создайте замещающий
+объект Notification в поле<code><a
+href="/reference/android/app/Notification.html#publicVersion">Notification.publicVersion</a></code>.
+
+ <li> Этот параметр предоставляет приложению возможность создавать "цензурированную" версию
+содержимого, достаточно информативную, но скрывающую личную информацию. Рассмотрим в качестве примера приложение для отправки
+SMS-сообщений. Его уведомления содержат текст SMS-сообщения и имя и контактный значок отправителя.
+Такое уведомление должно иметь атрибут <code>VISIBILITY_PRIVATE</code>, но его версия <code>publicVersion</code> может
+содержать полезную информацию, например, "3 новых сообщения", без уточняющих
+подробностей.
+ </ul>
+ </li>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_SECRET">Notification.VISIBILITY_SECRET</a></code>. Отображается минимум информации,
+даже без значка уведомления.</li>
+</ul>
+<h2 style="clear:both" id="notifications_on_android_wear">Уведомления на
+Android Wear</h2>
+
+<p>По умолчанию уведомления и их <em>действия</em> передаются на носимые устройства.
+Разработчики могут управлять тем, какие уведомления следует передавать с
+телефона на часы,
+и наоборот. У разработчиков также есть возможность управлять передачей действий. Если
+приложение включает в себя
+действия, которые невозможно выполнить одним касанием, нужно либо скрывать их
+в уведомлениях, отображаемых на носимом
+устройстве, либо обеспечить их привязку к приложению под управлением Android Wear, позволив пользователю
+совершать действие
+на часах.</p>
+
+<h4>Передача уведомлений и действий на другое устройство</h4>
+
+<p>Подключенное устройство, например, телефон, может передавать уведомления на носимое устройство,
+чтобы они отображались и на нем. Аналогичным образом можно передавать действия, чтобы пользователь мог реагировать
+на уведомления непосредственно на носимом устройстве.</p>
+
+<p><strong>Передавайте</strong></p>
+
+<ul>
+ <li> новые мгновенные сообщения;</li>
+ <li> действия, выполняемые одним касанием, например, "+1", "Лайк", "Сердечко".</li>
+</ul>
+
+<img src="{@docRoot}images/android-5.0/notifications/WearBasic.png" width="156px" height="156px" alt="" />
+
+<p><strong>Не передавайте</strong></p>
+
+<ul>
+ <li> уведомления о новых подкастах;</li>
+ <li> действия, соответствующие функциям, недоступным на часах.</li>
+</ul>
+
+
+
+<p><h4>Уникальные действия, определяемые для носимых устройств</h4></p>
+
+<p>Некоторые действия можно выполнить только на носимых устройствах, например:</p>
+
+<ul>
+ <li> выбор из списка шаблонных ответов, например, "Скоро вернусь"</li>
+ <li> действие "Открыть на телефоне";</li>
+ <li> действия "Прокомментировать" или "Ответить", открывающие окно речевого ввода;</li>
+ <li> действия, запускающие приложения, специфичные для Android Wear.</li>
+</ul>
+
+<img src="{@docRoot}images/android-5.0/notifications/ReplyAction.png" width="156px" height="156px" alt="" />
diff --git a/docs/html-intl/intl/ru/preview/api-overview.jd b/docs/html-intl/intl/ru/preview/api-overview.jd
new file mode 100644
index 0000000..ae30e09
--- /dev/null
+++ b/docs/html-intl/intl/ru/preview/api-overview.jd
@@ -0,0 +1,521 @@
+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">Поддержка пера Bluetooth</a></li>
+ <li><a href="#ble-scanning">Улучшенное сканирование Bluetooth с низким потреблением энергии</a></li>
+ <li><a href="#hotspot">Поддержка 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">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">API уровня 22 в M Preview &raquo;</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>M Developer Preview — ознакомительная версия предстоящего выпуска платформы Android,
+в котором реализованы новые возможности как для пользователей, так и для
+разработчиков приложений. В этой статье мы расскажем о наиболее интересных API-интерфейсах.</p>
+
+<p>Версия M Developer Preview предназначена для тех, <strong>кто хочет первым ознакомиться с новой платформой</strong>,
+а также для <strong>тестировщиков</strong>. <a href="{@docRoot}preview/setup-sdk.html">M Developer Preview — прекрасная возможность
+</a>повлиять на вектор развития
+платформы Android.
+Мы с нетерпением ждем ваших отзывов!</p>
+
+<p class="caution"><strong>Внимание!</strong> Не публикуйте в магазине Google Play приложения,
+предназначенные для M Developer Preview.</p>
+
+<p class="note"><strong>Примечание.</strong> В этой статье часто упоминаются классы и методы,
+для которых на сайте <a href="{@docRoot}">developer.android.com</a> пока еще нет справочных материалов. Такие элементы API-интерфейса обозначаются здесь следующим образом:
+{@code code style} (без гиперссылок). Чтобы ознакомиться с предварительной документацией по этим элементам,
+загрузите <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>В M Preview улучшена система намерений Android за счет более эффективного связывания приложений.
+Теперь у вас есть возможность связывать приложения с вашими собственными веб-доменами. Благодаря этому
+платформа может сама, без вмешательства пользователя, определить приложение, которое будет использоваться по умолчанию
+для обработки определенной веб-ссылки. О том, как реализовать такую возможность, можно почитать в статье
+<a href="{@docRoot}preview/features/app-linking.html">Связывание приложений</a>.
+
+<h2 id="backup">Автоматическое резервное копирование для приложений</h2>
+<p>Теперь система автоматически выполняет полное резервное копирование и восстановление данных ваших приложений. Для приложений,
+написанных под M Preview, эта функция включена по умолчанию — вам даже не нужно добавлять отдельный код. Если пользователь решит удалить свою учетную запись Google, все резервные копии его данных также будут удалены.
+ О том, как работает эта функция и как настроить параметры резервного копирования элементов файловой системы,
+ рассказано в статье
+<a href="{@docRoot}preview/backup/index.html">Автоматическое резервное копирование для приложений</a>.</p>
+
+<h2 id="authentication">Авторизация</h2>
+<p>В M Preview представлены новые API-интерфейсы, которые позволяют авторизовать пользователей по отпечатку пальца
+(на устройствах, поддерживающих такую возможность), а также подтвердить учетные данные, если пользователь недавно авторизовался через механизмы разблокировки устройства
+(например, вводил пароль для разблокировки экрана). Эти API-интерфейсы рекомендуется использовать совместно с
+<a href="{@docRoot}training/articles/keystore.html">системой хранилища ключей Android</a>.</p>
+
+<h3 id="fingerprint-authentication">Авторизация по отпечатку пальца</h3>
+
+<p>Чтобы авторизовать пользователя по отпечатку пальца, получите экземпляр нового класса
+{@code android.hardware.fingerprint.FingerprintManager} и вызовите метод
+{@code FingerprintManager.authenticate()}. Эта функция доступна для совместимых
+устройств, оснащенных сканером отпечатков пальцев. Прежде всего, вам необходимо реализовать в своем приложении пользовательский интерфейс проверки
+подлинности по отпечатку пальца, а также использовать для него стандартный значок отпечатка пальца 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>Установите инструменты SDK Android (версию 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>M Preview содержит 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>
+В M Preview представлен новый голосовой 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>
+M Preview предлагает новый способ взаимодействия пользователей с приложением — взаимодействие посредством помощника. Для этого
+пользователю необходимо разришить помощнику использовать текущий контекст, после чего он сможет вызывать помощника
+в любом приложении, удерживая кнопку <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">Поддержка пера Bluetooth</h2>
+<p>В M Preview улучшена поддержка ввода с помощью пера Bluetooth. Пользователи могут подключить
+совместимое перо Bluetooth к своему смартфону или планшету. Когда перо подключено, данные о его
+положении объединяются со сведениями о степени нажима и нажатия кнопки на пере,
+и таким образом при сенсорном вводе используются не только возможности сенсорного экрана. Ваше приложение может отслеживать
+нажатия кнопки пера и выполнять дополнительные действия, регистрируя в операции новые методы обратного вызова
+{@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 Preview, при нажатии пользователем на основную кнопку на пере, метод
+{@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">Улучшенное сканирование Bluetooth с низким потреблением энергии</h2>
+<p>
+Если ваше приложение выполняет сканирование Bluetooth с низким потреблением энергии, вы можете при помощи нового метода
+{@code android.bluetooth.le.ScanSettings.Builder.setCallbackType()} указать, что обратные вызовы следует уведомлять только в случае, если прежде обнаружен пакет объявления,
+ совпадающий с заданным фильтром
+{@link android.bluetooth.le.ScanFilter}, или если он не обнаруживается в течение заданного периода времени.
+ Такой подход к сканированию обеспечивает еще большую экономию энергии, чем это было возможно в предыдущей
+версии платформы.
+</p>
+
+<h2 id="hotspot">Поддержка Hotspot 2.0, выпуск 1</h2>
+<p>
+В M Preview включена поддержка Hotspot 2.0 (выпуск 1) для устройств Nexus 6 и Nexus 9. Для
+предоставления учетных данных Hotspot 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} показывает, является ли обнаруженная
+сеть точкой доступа Hotspot 2.0.
+</p>
+
+<h2 id="4K-display">Режим отображения в формате 4K</h2>
+<p>Теперь платформа позволяет приложениям запрашивать увеличение разрешения экрана до 4K при обработке изображения
+на совместимом устройстве. Чтобы запросить текущее физическое разрешение, используйте новые API-интерфейсы
+{@code android.view.Display.Mode}. Если элементы пользовательского интерфейса, отрисованные в более низком логическом разрешении, масштабируются до
+более высокого физического разрешения, обратите внимание, что метод физического разрешения
+{@code Display.Mode.getPhysicalWidth()} возвращает результат, который может отличаться от результата выполнения метода логического разрешения
+{@link android.view.Display#getSize(android.graphics.Point) getSize()} .</p>
+
+<p>Можно отправить запрос системе на изменение физического разрешения в активном приложении, задав для окна вашего приложения свойство
+{@code WindowManager.LayoutParams.preferredDisplayModeId}. Эта
+функция особенно полезна в случаях, когда требуется переключиться на разрешение экрана 4K. В режиме отображения в формате 4K элементы
+пользовательского интерфейса отрисовываются в исходном разрешении (например, 1080p) и масштабируются до 4K, однако содержимое
+{@link android.view.SurfaceView} объектов может отображаться с использованием основного разрешения.</p>
+
+<h2 id="behavior-themeable-colorstatelists">Метод ColorStateLists для работы с темами</h2>
+<p>Теперь метод
+{@link android.content.res.ColorStateList} для устройств под управлением M Preview поддерживает атрибуты темы. Методы
+{@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>В M Preview реализован ряд улучшений в области обработки аудиофайлов системой Android, включая следующие: </p>
+<ul>
+ <li>Новые API-интерфейсы {@code android.media.midi}, поддерживающие протокол <a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a>
+ для отправки и получения событий
+MIDI.</li>
+ <li>Новые классы: {@code android.media.AudioRecord.Builder} позволяет создавать объекты захвата цифрового аудио, а {@code android.media.AudioTrack.Builder} — объекты воспроизведения,
+а также осуществлять настройку источника
+аудио и свойств приемника, переопределяя исходные системные настройки.</li>
+ <li>Обработчики API-интерфейсов предназначены для связывания аудиофайлов и устройств ввода. Это особенно полезно в случае, если ваше приложение
+предоставляет возможность выполнять голосовой поиск с помощью игрового контроллера или пульта дистанционного управления, подключенного к 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>В M Preview вы обнаружите новые возможности 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>В M Preview представлены следующие API-интерфейсы для вспышки камеры и повторной обработки
+изображений камерой.</p>
+
+<h3 id="flashlight">API-интерфейс вспышки</h3>
+<p>Если камера оснащена вспышкой, вы можете вызвать метод{@code CameraManager.setTorchMode()},
+чтобы включить или отключить режим фонарика, не запуская камеру. Приложение
+не может заполучить вспышку или камеру в единоличное пользование. Режим фонарика отключается
+и становится недоступен, когда камера недоступна или ресурсов камеры недостаточно для использования вспышки в качестве
+фонарика. Кроме того, другие приложения могут вызывать метод {@code setTorchMode()}
+для отключения режима фонарика. При закрытии приложения, которое включило режим фонарика, этот режим
+отключается.</p>
+
+<p>Чтобы зарегистрировать обратный вызов для уведомления о режиме фонарика, вызовите метод
+{@code CameraManager.registerTorchCallback()}. При первой регистрации обратного вызова
+он сразу же вызывается со сведениями о состоянии режима фонарика для всех известных к настоящему моменту устройств,
+оснащенных вспышкой. При успешном включении или отключении фонарика вызывается метод
+{@code CameraManager.TorchCallback.onTorchModeChanged()}.</p>
+
+<h3 id="reprocessing">API-интерфейс повторной обработки</h3>
+<p>API-интерфейс {@link android.hardware.camera2 Camera2} теперь поддерживает повторную обработку цветовых моделей 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 ImageFormat.PRIVATE} прямо в
+{@code ImageWriter}, вызвав метод {@code ImageWriter.queueInputImage()} без копии
+буфера.</p>
+
+<p>Класс {@code ImageReader} теперь поддерживает потоки изображений в формате {@code android.graphics.ImageFormat.PRIVATE}.
+ Благодаря этому ваше приложение может организовать циклическую очередь выходных изображений
+{@code ImageReader}, выбрать одно или несколько изображений и отправить их в
+{@code ImageWriter} для повторной обработки камерой.</p>
+
+<h2 id="afw">Возможности Android for Work</h2>
+<p>В M Preview представлены новые API-интерфейсы для Android for Work:</p>
+<ul>
+ <li><strong>Улучшенные элементы управления для корпоративных специализированных устройств.</strong> Владельцу устройства
+теперь доступны новые возможности управления
+корпоративными специализированными устройствами при помощие следующих настроек:
+ <ul>
+ <li>Отключение или повторное включение блокировки клавиатуры с помощью метода
+{@code DevicePolicyManager.setKeyguardEnabledState()}.</li>
+ <li>Отключение или повторное включение строки состояния (включая быстрые настройки, уведомления и
+запуск Google Now путем проведения пальцем по экрану) с помощью метода
+{@code DevicePolicyManager.setStatusBarEnabledState()}.</li>
+ <li>Отключение и повторное включение безопасной загрузки с помощью константы
+{@code DISALLOW_SAFE_BOOT} {@link android.os.UserManager}.</li>
+ <li>Предотвращение отключения экрана, если устройство питается от сети, с помощью константы
+{@code STAY_ON_WHILE_PLUGGED_IN} {@link android.provider.Settings.Global}.</li>
+ </ul>
+ </li>
+ <li><strong>Автоматические установка и удаление приложений владельцами устройств.</strong> Владелец устройства теперь может автоматически
+устанавливать и удалять приложения с помощью API-интерфейсов {@link android.content.pm.PackageInstaller},
+независимо от Google Play for Work. Теперь вы можете подготавливать устройства с помощью компонента «Владелец устройства», который
+получает и устанавливает приложения без участия пользователя. Такая возможность особенно полезна тем, что позволяет подготавливать
+киоски или иные подобные устройства одним касанием, не активируя аккаунт 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> Владелец профиля или устройства теперь может предоставлять
+стороннему приложению возможность вызывать следующие API-интерфейсы управления сертификатом
+{@link android.app.admin.DevicePolicyManager}:
+<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> При подготовке компонента «Владелец устройства» теперь
+имеется возможность настроить параметры разблокировки защиты от сброса параметров до заводских настроек (FRP) путем задания пакета
+{@code DeviceManagerPolicy.EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS}. Приложение NFC Programmer
+может после перезагрузки устройства предоставить эти параметрыс целью разблокировки FRP и его подготовки
+(без необходимости запрашивать ранее настроенную учетную запись Google). Если не изменить эти параметры,
+заводские настройки сохранятся не позволят активировать устройство без ввода активированных ранее
+учетных данных 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> Владелец профиля или устройства теперь может запрашивать статистику использования
+данных, которая отображается в разделе <strong>Настройки &gt; Использование данных</strong>, с помощью новых методов
+{@code android.app.usage.NetworkStatsManager}. Владельцам профилей автоматически предоставляется
+разрешение запрашивать данные профиля, которым они управляют, тогда как владельцам устройств предоставляется доступ к сведениям об использовании данных
+основного управляемого пользователя.</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">
+ Подробные сведения обо всех изменениях в API-интерфейсах в версии M Developer Preview представлены в <a href="{@docRoot}preview/download.html">отчете о различиях между API-интерфейсами</a>.
+</p>
diff --git a/docs/html-intl/intl/ru/preview/behavior-changes.jd b/docs/html-intl/intl/ru/preview/behavior-changes.jd
new file mode 100644
index 0000000..0623ea7
--- /dev/null
+++ b/docs/html-intl/intl/ru/preview/behavior-changes.jd
@@ -0,0 +1,402 @@
+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">Отказ от HTTP-клиента Apache</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">API уровня 22 в M Preview &raquo;</a> </li>
+</ol>
+
+
+<h2>См. также:</h2>
+<ol>
+<li><a href="{@docRoot}preview/api-overview.html">Обзор API-интерфейсов M Developer Preview</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>Наряду с новыми функциями и возможностями, версия M Developer Preview также включает в себя ряд
+системных изменений и изменений в работе API-интерфейсов. В этом документе рассматриваются
+определенные ключевые изменения, о которых следует знать, чтобы учитывать их при разработке приложений.</p>
+
+<p>Если вы ранее публиковали приложения для Android, то примите во внимание,
+что эти изменения в платформе могут повлиять на работу ваших уже опубликованных приложений.</p>
+
+<h2 id="behavior-runtime-permissions">Разрешения на выполнение</h1>
+<p>В M Preview представлена новая модель разрешений: теперь пользователи могут управлять разрешениями приложений
+напрямую во время работы с ними. Такая модель обеспечивает улучшенное управление
+разрешениями и одновременно позволяет оптимизировать установку и автоматическое обновление для разработчиков.
+Пользователи могут предоставлять разрешения или отзывать их отдельно для каждого установленного приложения. </p>
+
+<p>В ваших приложениях, предназначенных для M Preview, следует в обязательном порядке проверить такие разрешения и при необходимости
+запросить их. Чтобы определить, было ли вашему приложению предоставлено разрешение, вызовите новый метод
+{@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>В M Preview реализован ряд новых функций оптимизации экономии энергии для неактивных устройств и приложений.</p>
+
+<h3 id="behavior-doze">Режим «Doze»</h3>
+<p>Если устройство отключено от сети и остается неактивным (и с выключенным экраном) в течение определенного времени,
+оно переходит в режим <em>Doze</em> и старается, чтобы система не выходила из спящего состояния. В этому режиме
+устройство периодически возобновляет свою обычную работу на краткие промежутки времени, чтобы произвести
+синхронизацию и позволить системе выполнить какие-либо отложенные операции.</p>
+
+<p>Когда устройство находится в режиме «Doze», к приложениям применяются следующие ограничения:</p>
+<ul>
+<li>Доступ к сети отключен до тех пор, пока от службы Google Cloud Messaging
+не будет получен высокоприоритетный сигнал побуждения приложения к действию.</li>
+<li>Механизмы <a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">WakeLock</a> игнорируются.</li>
+<li>Будильники, установленные с помощью класса {@link android.app.AlarmManager}, отключаются, кроме
+тех, которые установлены с помощью методов {@link android.app.AlarmManager#setAlarmClock setAlarmClock()}
+и {@code AlarmManager.setAndAllowWhileIdle()}.</li>
+<li>Поиск сетей Wi-Fi не производится.</li>
+<li>Операции синхронизации и заданий для адаптеров синхронизации и {@link android.app.job.JobScheduler} блокируются.
+</li>
+</ul>
+</p>
+<p>После выхода из режима «Doze», устройство приступает к выполнению любых отложенных заданий и операций синхронизации.</p>
+<p>Чтобы протестировать эту функцию, подключите устройство под управлением M Preview к своему компьютеру
+для разработки и выполните следующие команды:
+</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 Messaging</a>
+реализована возможность назначения сообщений
+с высоким приоритетом. При получении вашим приложением сообщений GCM с высоким приоритетом ему на короткое время предоставляется
+доступ к сети, даже если устройство находится в режиме «Doze».
+</p>
+
+<p>Советы по тестированию работы приложений в режиме «Doze» представлены
+в <a href="{@docRoot}preview/testing/guide.html#doze-standby">руководстве
+по тестированию</a>. </p>
+
+<h3 id="behavior-app-standby">Ждущий режим для приложений</h3>
+<p>В M Preview система может определять, что приложения неактивны, когда они
+не используются. Приложение считается неактивным по прошествии определенного периода времени до тех пор, пока система
+не обнаружит один из следующих сигналов:</p>
+
+<ul>
+<li>приложение явным образом запущено пользователем;</li>
+<li>у приложения имеется процесс, который в настоящее время выполняется на переднем плане (это может быть как сама операция или служба переднего плана,
+так и процесс, используемый другой операцией или службой переднего плана).</li>
+<li>приложение создает уведомление, которое пользователи видят на экране блокировки или в
+области уведомлений.</li>
+<li>пользователь явным образом исключает приложение из списка для оптимизации
+в разделе <strong>Настройки</strong>.</li>
+</ul>
+
+<p>Если устройство отключено от электросети, для приложений, которые считаются неактивными, закрывается доступ к Интернету,
+а их операции синхронизации и задания приостанавливаются. После подключения устройства к электросети доступ к Интернету для приложений возобновится
+и они смогут приступить к выполнению любых ожидающих заданий и операций синхронизации. Если устройство
+неактивно в течение длительного времени, неактивным приложениям раз в день предоставляется доступ к сети.</p>
+
+<p>Чтобы протестировать эту функцию, подключите устройство под управлением M Preview к своему компьютеру
+для разработки и выполните следующие команды:
+</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 Messaging</a> (GCM)
+реализована возможность назначения сообщений
+с высоким приоритетом. При получении вашим приложением сообщений GCM с высоким приоритетом ему на короткий промежуток времени предоставляется
+доступ к сети, даже если приложение находится в неактивном состоянии.
+</p>
+
+<p>Советы по тестированию работы приложений в ждущем режиме представлены
+в <a href="{@docRoot}preview/testing/guide.html#doze-standby">руководстве
+по тестированию</a>. </p>
+
+<h2 id="behavior-adoptable-storage">Подключаемые устройства хранения</h2>
+<p>
+В M Preview пользователи могут <em>подключать</em> внешние устройства хранения, такие как SD-карты, и использовать их как внутреннее хранилище,
+зашифровав и отформатировав требуемым образом. Благодаря этому
+ пользователи могут переносить как сами приложения, так свои файлы для этих приложений с одного устройства хранения на другое. При переносе
+приложений система руководствуется настройкой
+<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>Для отладки этой функции в Developer Preview подключите USB-устройство,
+ к устройству Android посредством USB-кабеля On-The-Go (OTG) и выполните следующую команду:</p>
+
+<pre class="no-prettyprint">
+$ adb shell sm set-force-adoptable true
+</pre>
+
+<h2 id="behavior-apache-http-client">Отказ от HTTP-клиента Apache</h2>
+<p>В M Preview удалена поддержка HTTP-клиента Apache. Если ваше приложение, разработанное для
+Android 2.3 (уровень API 9) или более поздней версии, использует этот клиент, вам необходимо воспользоваться вместо него классом {@link java.net.HttpURLConnection}.
+ Этот API-интерфейс более эффективный, поскольку он сокращает использование сетевого трафика за счет прозрачного сжатия
+и кэширования ответов, а также сводит к минимуму потребление энергии. Чтобы продолжить использовать API-интерфейсы HTTP Apache,
+сначала объявите в своем файле {@code build.gradle} следующую зависимость compile-time:
+</p>
+<pre>
+android {
+ useLibrary 'org.apache.http.legacy'
+}
+</pre>
+<p>Вместо OpenSSL в Android теперь будет использоваться библиотека
+<a href="https://boringssl.googlesource.com/boringssl/" class="external-link">BoringSSL</a>
+. Если вы используете в ваших приложениях Android NDK, не связывайте его с криптографическими библиотеками,
+которые не входят в состав API-интерфейса NDK, такими как {@code libcrypto.so} и {@code libssl.so}. Эти библиотеки
+не являются общедоступными API-интерфейсами, и в разных выпусках или на разных устройствах они могут быть изменены или разбиты без предварительного уведомления.
+Кроме того, этим вы можете создать уязвимости в системе безопасности вашего продукта. Вместо этого внесите изменения в
+собственный код для вызова криптографических API-интерфейсов Java посредством JNI или статической ссылки на
+библиотеку криптографии по своему выбору.</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, то помните, что перемещаемым панелям инструментов
+не свойственна обратная совместимость и по умолчанию для управления объектами {@link android.view.ActionMode}
+используется библиотека appcompat. Это означает, что перемещаемые панели инструментов не будут отображаться. Чтобы включить поддержку
+{@link android.view.ActionMode} в
+{@link android.support.v7.app.AppCompatActivity}, вызовите метод
+{@code android.support.v7.app.AppCompatActivity.getDelegate()}, затем вызовите
+{@code android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled()} для возвращенного объекта
+{@link android.support.v7.app.AppCompatDelegate} и задайте для параметра input
+значение {@code false}. Этот вызов возвращает управление объектами {@link android.view.ActionMode}
+платформе. На устройствах под управлением M Preview платформа поддерживает как режимы
+{@link android.support.v7.app.ActionBar}, так и режимы перемещаемых панелей инструментов, тогда как на устройствах под управлением более ранних версий
+поддерживаются только режимы {@link android.support.v7.app.ActionBar}.</p>
+
+<h2 id="behavior-keystore">Изменения в хранилище ключей Android</h2>
+<p>В M Preview
+<a href="{@docRoot}training/articles/keystore.html">поставщик хранилища ключей Android</a> больше не поддерживает
+DSA. ECDSA по-прежнему поддерживается.</p>
+
+<p>Ключи, для которых не требуется шифрование в хранилище, больше не будут удаляться при отключении или сбросе защищенного экрана блокировки
+(например, пользователем или администратором устройства). Ключи, для которых требуется шифрование
+в хранилище, во время таких событий будут удалены.</p>
+
+<h2 id="behavior-network">Изменения в работе с Wi-Fi и сетями</h2>
+
+<p>Ниже перечислены изменения в API-интерфейсах для работы с Wi-Fi и сетями, реализованные в M Preview.</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}, то устройство отключалось от других сетей, например, от
+сотовой сети. В M Preview устройство больше не отключается от других сетей. Если
+в вашем приложении для параметра {@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>В M Preview изменена модель получения доступа к ресурсам в службе камеры.
+ Если раньше запросы доступа обрабатывались в порядке поступления, то теперь процессы с высоким приоритетом имеют преимущество.
+ В работе службы камеры произошли следующие изменения:</p>
+<ul>
+<li>Доступ к ресурсам подсистемы камеры, включая открытие и настройку устройства камеры,
+предоставляется в зависимости от того, какой приоритет имеет процесс клиентского приложения. Процессы приложений с операциями, которые
+видны пользователю или выполняются на переднем плане, обычно имеют более высокий приоритет, что повышает возможность доступа к ресурсам камеры и их
+использования.</li>
+<li>Когда приложение с более высоким приоритетом пытается использовать камеру, активные клиенты камеры для приложений с более низким приоритетом могут быть исключены из очереди доступа.
+ В устаревшем API-интерфейсе {@link android.hardware.Camera}
+это приводит к вызову
+{@link android.hardware.Camera.ErrorCallback#onError(int,android.hardware.Camera) onError()}
+для исключенного клиента. В API-интерфейсе {@link android.hardware.camera2 Camera2} в таких случаях для исключенного клиента вызывается
+{@link android.hardware.camera2.CameraDevice.StateCallback#onDisconnected(android.hardware.camera2.CameraDevice) onDisconnected()}.
+</li>
+<li>На устройствах, где камера позволяет такое, отдельным процессам
+приложения предоставляется возможность одновременно и независимо друг от друга открывать и использовать ресурсы камеры. При этом служба камеры теперь отслеживает и исключает ситуации с использованием ресурсов несколькими процессами,
+когда одновременный доступ вызывает значительное снижение производительности или негативно влияет на возможности
+всех открытых камер. Это изменение
+может привести к отключению доступа для клиентов с более низким приоритетом, даже если к этой же камере не пытаются получить доступ другие приложения.
+
+</li>
+<li>
+Смена пользователя приводит к исключению активных клиентов камеры в приложениях, относящихся к предыдущей учетной записи,
+из очереди доступа. Доступ к камере предоставлен только профилям, которыми владеет активный пользователь устройства.
+Фактически это означает, что если, например, пользователь переключился с гостевой учетной записи на другую, гостевой аккаунт не сможет покинуть запущенные процессы
+, использующие ресурсы подсистемы камеры.
+</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()}, присвоив параметру input
+значение {@code true}. Если ваше приложение использует
+<a href="{@docRoot}tools/support-library/features.html#v7-appcompat">библиотеку appcompat v7</a> или
+<a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">библиотеку recyclerview v7</a>,
+вам необходимо установить актуальные версии этих библиотек. В противном случае убедитесь в том,
+что любые настраиваемые классы, на которые имеются ссылки из XML, обновлены и их конструкторы классов доступны.</p>
+
+<p>В M Preview обновлено поведение динамического компоновщика. Теперь он распознает разницу между
+{@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>В M Preview правильно реализован флаг {@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>В M Preview представлены следующие изменения работы Android for Work:</p>
+<ul>
+<li><strong>Рабочие контакты в контексте личных сведений.</strong> Теперь при просмотре пользователем прошлых звонков в журнале вызовов Google Dialer
+в нем отображаются и рабочие контакты.
+Чтобы скрыть эти сведения в журнале вызовов, установите для параметра {@code DevicePolicyManager.setCrossProfileCallerIdDisabled()} значение {@code true}.
+ Рабочие контакты могут отображаться на устройствах через Bluetooth вместе с
+личными контактами только в том случае, если
+для параметра {@code DevicePolicyManager.setBluetoothContactSharingDisabled()} задано значение {@code false}. По
+умолчанию для этого параметра установлено значение {@code true}.
+</li>
+<li><strong>Удаление конфигурации Wi-Fi.</strong> Конфигурации Wi-Fi, добавленные владельцем профиля
+(например, посредством вызова метода
+{@link android.net.wifi.WifiManager#addNetwork(android.net.wifi.WifiConfiguration)
+addNetwork()}), теперь удаляются при удалении соответствующего рабочего профиля.</li>
+<li><strong>Блокировка конфигурации Wi-Fi.</strong> Пользователю больше не удастся изменить или удалить любые конфигурации Wi-Fi, созданные активным
+владельцем устройства. Пользователь по-прежнему может создавать
+и изменять свои собственные конфигурации Wi-Fi, если для этого пользователя не задана константа
+{@link android.os.UserManager#DISALLOW_CONFIG_WIFI} {@link android.os.UserManager}.</li>
+<li><strong>Загрузка приложения «Контроллер политики работы» путем добавления учетной записи Google.</strong> Теперь при добавлении на устройство учетной записи Google,
+для управления которой требуется приложение «Контроллер политики работы»,
+вне управляемого контекста пользователю предлагается установить соответствующее приложение.
+Это также применимо к учетным записям, добавляемым посредством мастера первоначальной настройки устройства в разделе
+<strong>Настройки &gt; Учетные записи</strong>.</li>
+<li><strong>Изменения, касающиеся работы API-интерфейса DevicePolicyManager.</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/ru/preview/features/runtime-permissions.jd b/docs/html-intl/intl/ru/preview/features/runtime-permissions.jd
new file mode 100644
index 0000000..7d12b2d
--- /dev/null
+++ b/docs/html-intl/intl/ru/preview/features/runtime-permissions.jd
@@ -0,0 +1,794 @@
+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>Если ваше приложение предназначено для пакета SDK M Preview, пользователю будет предложено предоставить для него разрешения
+ не в процессе установки, а при работе с приложением.</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 Developer Preview представлена новая модель разрешений для приложений, которая
+оптимизирует для пользователей процесс установки и обновления приложений. Если приложение,
+работающее в M Preview, поддерживает новую модель разрешений, пользователю не нужно предоставлять какие-либо
+разрешения при установке приложения или его обновлении. Вместо этого приложение
+запрашивает разрешения, когда в них возникает необходимость, — в таких случаях система отображает для пользователя диалоговое окно с просьбой предоставить
+соответствующее разрешение.
+</p>
+
+<p>
+ Если приложение поддерживает новую модель разрешений, его, тем не менее, можно установить и
+запустить на устройстве под управлением одной из более ранних версий Android, и оно будет использовать старую модель
+разрешений.
+</p>
+
+<h2 id="overview">
+ Обзор
+</h2>
+
+<p>
+ В версии M Developer Preview представлена новая
+модель разрешений. Ниже приводится краткий обзор ее ключевых компонентов:
+</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 Developer Preview, оно
+<em>должно в обязательном порядке</em> использовать новую модель разрешений.
+</p>
+
+<p>
+ На момент выпуска M Developer Preview не все приложения Google в полной мере реализуют
+ новую модель разрешений. Google обновляет эти приложения
+по мере разработки M Developer Preview, чтобы они должным образом поддерживали настройки
+разрешений.
+</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>название_приложения</i> <strong>&gt; Разрешения</strong>. Поэтому приложение все равноу
+должно проверять наличие разрешений во время выполнения и при необходимости запрашивать их.
+
+</p>
+
+<h3 id="compatibility">
+ Совместимость с предыдущими и последующими версиями
+</h3>
+
+<p>
+ Если приложение не предназначено для M Developer Preview, оно
+продолжает использовать старую модель разрешений даже на устройствах под управлением M Preview. В таком случае при установке приложения
+ система предлагает пользователю предоставить все разрешения,
+указанные в манифесте приложения.
+</p>
+
+<p class="note">
+ <strong>Примечание.</strong> На устройствах под управлением M Developer Preview пользователь может отключить
+разрешения для любого приложения (включая устаревшие приложения) на экране «Настройки».
+ Если пользователь решит отключить разрешения для устаревших приложений, система
+автоматически отключит соответствующие функциональные возможности. Когда приложение пытается
+выполнить операцию, для которой требуется такое разрешение, это
+не обязательно приведет к возникновению исключения. Вместо этого оно может выдать пустой набор данных,
+сигнал об ошибке или иным образом обозначить непредвиденное поведение. Например, если запросить
+календарь, не имея соответствующего разрешения, метод возвратит пустой набор данных.
+</p>
+
+<p>
+ При установке приложения с использованием новой модели разрешений на устройство
+под управлением другой версии ОС, отличной от M Preview,
+система рассматривает такое приложение как любое другое и предлагает
+пользователю предоставить все объявленные разрешения уже во время установки.
+</p>
+
+<p class="note">
+ <strong>Примечание.</strong> В случае с предварительной версией в качестве минимальной версии пакета SDK
+следует задать версию SDK M Preview, чтобы получить возможность компилировать код с помощью пакета SDK предварительной версии. Это означает,
+что вы не сможете протестировать такие приложения на старых платформах
+во время использования предварительной версии для разработчиков.
+</p>
+
+<h3 id="perms-vs-intents">Разрешения и намерения</h3>
+
+<p>
+ Во многих случаях при разработке приложения у вас есть выбор между двумя способами выполнения задачи:
+ вы можете настроить приложение таким образом, чтобы оно самостоятельно запрашивало соответствующие разрешения на выполнение
+операции, или же можно указать ему использовать намерение, чтобы задачу выполнило
+другое приложение.
+</p>
+
+<p>
+ Например, предположим, что вашему приложению требуется возможность делать снимки с помощью камеры устройства.
+ Ваше приложение может запросить разрешение
+<code>android.permission.CAMERA</code>, которое позволит ему напрямую получить доступ
+к камере. Затем ваше приложение использует API-интерфейсы камеры
+для управления камерой и получения снимков. Благодаря такому подходу ваше приложение получает
+полный контроль над процессом фотографирования. Кроме того, это позволяет вам вставить пользовательский интерфейс камеры
+в свое приложение.
+</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>Ваше приложение получает полный контроль над взаимодействием пользователя с интерфейсом во время выполнения
+операции. Однако такой широкий контроль усложняет вашу задачу,
+требуя разработать подходящий пользовательский интерфейс.
+ </li>
+
+ <li>Пользователю предлагается предоставить разрешения только один раз, при первом
+выполнении операции. После этого ваше приложение может выполнять операцию без вмешательства
+со стороны пользователя. Однако если пользователь не
+предоставит разрешение (или отзовет его позже), ваше приложение не сможет выполнить
+операцию.
+ </li>
+</ul>
+
+<p>
+ При использовании намерений:
+</p>
+
+<ul>
+ <li>Вам не нужно разрабатывать пользовательский интерфейс для выполнения операции, его предоставляет приложение, которое обрабатывает
+намерение. Однако это также означает, что у вас отсутствует контроль над
+взаимодействием пользователя с интерфейсом. Возможно, пользователю придется взаимодействовать с
+приложением, которое вы даже не видели.
+ </li>
+
+ <li>Если у пользователя нет приложения по умолчанию для выполнения операции, система
+предлагает ему выбрать приложение. Если пользователь не назначит обработчик
+по умолчанию, то при каждом выполнении операции для него может
+отображаться дополнительное диалоговое окно.
+ </li>
+</ul>
+
+<h2 id="coding">Добавление в код разрешений на выполнение</h2>
+
+<p>
+ Если ваше приложение предназначено для новой версии M Developer Preview, вы должны в обязательном порядке использовать
+новую модель разрешений. Это означает, что кроме объявления требуемых разрешений
+в манифесте, вам следует проверять наличие этих разрешений
+во время выполнения, а также запрашивать их, если у вас
+еще нет необходимых разрешений.
+</p>
+
+<h3 id="enabling">
+ Активация новой модели разрешений
+</h3>
+
+<p>
+ Чтобы активировать новую модель разрешений M Developer Preview, задайте для атрибута
+<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 Preview
+</h3>
+
+<p>
+ В манифесте приложения можно использовать новый элемент <code>&lt;uses-permission-sdk-m&gt;</code>,
+чтобы указать, что разрешение требуется только для M Developer Preview. Если объявить
+разрешение таким способом, то при установке приложения на устройство с более старой версией платформы
+система не будет отправлять запрос пользователю или предоставлять разрешение приложению.
+С помощью элемента <code>&lt;uses-permission-sdk-m&gt;</code>
+вы можете добавлять новые разрешения
+в обновленные версии вашего приложения без принудительного запроса у пользователей разрешений при
+установке обновления.
+</p>
+
+<p>
+ Если приложение запущено на устройстве под управлением M Developer Preview,
+поведение элемента <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 Developer Preview, то при первом запуске приложения
+на устройстве под управлением
+M Preview пользователю не предлагается предоставить все разрешения. Вместо этого приложение само запрашивает разрешения, когда они
+требуются. Когда приложение запрашивает разрешение, система отображает для пользователя соответствующее диалоговое
+окно.
+</p>
+
+<p>
+ Если ваше приложение запущено на устройстве с пакетом SDK уровня 22 или более низкого, то приложение использует старую
+модель разрешений. То есть при каждой устновке приложения пользователю будет предложено предоставить приложению все разрешения,
+запрашиваемые в манифесте приложения, кроме
+отмеченных элементом <code>&lt;uses-permission-sdk-m&gt;</code>.
+</p>
+
+<h4 id="check-platform">Проверка платформы, на которой выполняется приложение</h4>
+
+<p>
+ Новая модель разрешений поддерживается только на устройствах под управлением M Developer
+Preview. Прежде чем вызывать любые из этих методов, приложению следует проверить,
+на какой платформе оно выполняется,
+обратившись к значению параметра {@link android.os.Build.VERSION#CODENAME
+Build.VERSION.CODENAME}. Если устройство работает под управлением M Developer Preview,
+то значение параметра{@link android.os.Build.VERSION#CODENAME CODENAME} будет <code>"MNC"</code>.
+</p>
+
+<h4 id="check-for-permission">Проверка наличия у приложения необходимого разрешения</h4>
+
+<p>Когда пользователи пытаются выполнить какое-либо действие, для которого требуется разрешение, приложение
+проверяет, имеется ли у него в настоящее время разрешение на выполнение этой операции. Для этого
+приложение вызывает метод
+<code>Context.checkSelfPermission(<i>permission_name</i>)</code>. Приложению
+следует выполнять такую проверку даже в том случае, если ему известно, что пользователь уже предоставил
+необходимое разрешение,
+поскольку пользователь может в любое время отозвать разрешения приложения. Например, если пользователь
+хочет получить снимок с помощью приложения, то приложение вызывает метод
+<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 Developer Preview, то вы должны протестировать
+его и убедиться в том, что оно должным образом обрабатывает разрешения. Не надо исходить из того, что к началу работы ваше приложение уже имеет
+любые определенные разрешения. При первом запуске приложения оно,
+скорее всего, не будет обладать разрешениями, а в дальнейшем пользователь может в любой момент отозвать или восстановить
+разрешения.
+</p>
+
+<p>
+ Вам следует протестировать ваше приложение и убедиться в том, что оно ведет себя должным образом в
+любых ситуациях, касающихся разрешений. Мы включили в состав пакета SDK M Preview SDK новые команды
+<a href="{@docRoot}tools/help/adb.html">Android
+Debug Bridge (ADB)</a>, чтобы вы могли протестировать ваше приложение с любыми настройками разрешений,
+которые вы хотите попробовать в действии.
+</p>
+
+<h3>
+ Новые команды и параметры ADB
+</h3>
+
+<p>
+ В состав пакета инструментов SDK M Preview входит ряд новых команд, позволяющих протестировать обработку разрешений
+вашим приложением.
+</p>
+
+<h4>
+ Установка с разрешениями
+</h4>
+
+<p>
+ Можно воспользоваться новым параметром <code>-g</code> команды <a href="{@docRoot}tools/help/adb.html#move"><code>adb
+ install</code></a>, который служит для установки
+приложения и предоставления всех разрешений, указанных в его манифесте:
+</p>
+
+<pre class="no-pretty-print">
+$ adb install -g &lt;path_to_apk&gt;
+</pre>
+
+<h4>
+ Предоставление разрешений и их отзыв
+</h4>
+
+<p>
+ Для предоставления разрешений установленному приложению и их отзыва можно использовать новые команды <a href="{@docRoot}tools/help/adb.html#pm">диспетчера пакетов</a>
+ADB.
+Такая функциональная возможность может быть полезна для автоматизированного тестирования.
+</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/ru/preview/overview.jd b/docs/html-intl/intl/ru/preview/overview.jd
new file mode 100644
index 0000000..6ed1d20
--- /dev/null
+++ b/docs/html-intl/intl/ru/preview/overview.jd
@@ -0,0 +1,362 @@
+page.title=Обзор программы
+page.metaDescription=Добро пожаловать в программу Android M Developer Preview, участники которой получают всё необходимое для тестирования и оптимизации своих приложений для следующей версии платформы Android.
+page.image=images/cards/card-preview_16-9_2x.png
+page.tags="preview", "developer", "android"
+
+@jd:body
+
+<p>
+ Добро пожаловать в программу <strong>Android M Developer Preview</strong>, участники которой получают всё необходимоедля тестирования и оптимизации своих приложений для следующей версии платформы Android.
+
+ Это бесплатная программа, и приступить к ее использованию можно прямо сейчас, загрузив
+инструменты M Developer Preview.
+</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 (для Android TV), а также в эмуляторе.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Самый актуальный код платформы
+ </h5>
+
+ <p>
+ Во время знакомства с предварительной версией платформы мы будем предоставлять различные обновления, поэтому вы сможете протестировать самые актуальные изменения в платформе.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Получение обновлений по беспроводной связи
+ </h5>
+
+ <p>
+ После прошивки своего устройства для работы с предварительной версией платформы вы сможете получать обновления по беспроводной связи.
+
+ </p>
+ </div>
+ </div>
+
+ <div class="cols">
+
+
+ <div class="col-4of12">
+ <h5>
+ Новые возможности и новые функции
+ </h5>
+
+ <p>
+ Начните уже заранее реализовывать в своих приложениях поддержку расширенной функциональности платформы, например, новую модель разрешений на выполнение и функции сбережения энергии.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Приоритетная обработка отчетов об ошибках от разработчиков
+ </h5>
+
+ <p>
+ В течение первых нескольких недель мы будем рассматривать отчеты об ошибках, поступающие от разработчиков, в приоритетном порядке, поэтому не теряйте времени и приступайте к тестированию и составлению отзывов как можно раньше.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Отзывы и поддержка
+ </h5>
+
+ <p>
+ Отправляйте нам отчеты об ошибках и предоставляйте свои отзывы с помощью нашей <a href="https://code.google.com/p/android-developer-preview/">системы отслеживания проблем</a>.
+ Обменивайтесь идеями и предложениями с другими разработчиками в <a href="http://g.co/dev/AndroidMDevPreview">сообществе разработчиков Android&nbsp;M</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 Developer Preview запланировано на период с 28 мая до выпуска окончательной версии пакета SDK Android M, который
+состоится незадолго до публикации новой платформы в открытом доступе в
+третьем квартале 2015 г.
+</p>
+
+<p>
+ На ключевых этапах разработки платформы мы предоставим обновления для тестовых устройств.
+ Ниже перечислены предварительные даты этих ключевых этапов.
+</p>
+
+<ul>
+ <li>
+ <strong>Preview&nbsp;1</strong> (первоначальный выпуск версии Preview, конец мая)
+ </li>
+
+ <li>
+ <strong>Preview&nbsp;2</strong> (конец июня/начало июля)
+ </li>
+
+ <li>
+ <strong>Preview&nbsp;3</strong> (почти окончательный выпуск, конец июля)
+ </li>
+</ul>
+
+<p>
+ Завершающим этапом обновлений станет выход <strong>окончательной версии пакета SDK</strong> (в третьем квартале),
+где будут представлены официальные API-интерфейсы для новой версии Android, а также
+окончательные версии функций и поведений системы.
+</p>
+
+<p>
+ Мы настоятельно рекомендуем вам в ходе тестирования и разработки приложений для Android M <strong>постоянно
+обновлять вашу среду разработки</strong> по мере выхода обновлений для версии Preview.
+ Чтобы упростить этот процесс, мы будем отправлять на устройства, которые уже прошиты для работы с предварительной версией платформы, <strong>обновления по беспроводной сети</strong>.
+Мы также будем предоставлять вам системные образы, которые можно
+загрузить и использовать для прошивки устройства вручную.
+</p>
+<p class="note">
+ <strong>Примечание.</strong> Окончательные версии пакета SDK и системных образов не будут отправляться по беспроводной сети,
+их придется <strong>вручную установить</strong> на
+тестовые устройства.</strong>
+</p>
+
+<p>
+ Мы будем сообщать о появлении обновлений для версии Preview в <a href="http://android-developers.blogspot.com/">блоге разработчиков Android</a>, а
+также на этом сайте и в
+<a href="http://g.co/dev/AndroidMDevPreview">сообществе разработчиков Android M</a>.
+</p>
+
+<h2 id="preview_tools">
+ Что входит в состав Preview?
+</h2>
+
+<p>
+ M Developer Preview содержит всё, что вам необходимо для тестирования ваших существующих приложений на экранах различных размеров,
+тестирования с использованием различных сетевых технологий, чипсетов ЦП и графических процессоров,
+ а также на различных архитектурах оборудования.
+</p>
+
+<h4>
+ Инструменты SDK
+</h4>
+
+<p>
+ С помощью менеджера SDK в <a href="{@docRoot}sdk/installing/adding-packages.html">Android Studio</a> вы можете загрузить следующие компоненты:
+</p>
+
+<ul>
+ <li><strong>Инструменты SDK</strong> для M Developer Preview.
+ </li>
+
+ <li><strong>Системный образ эмулятора</strong> (32- и
+64-разрядная версии) для M Developer Preview.
+ </li>
+
+ <li><strong>Системный образ эмулятора для Android TV</strong> (32- и
+32-разрядная версии)
+ </li>
+</ul>
+
+<h4>
+ Системные образы оборудования
+</h4>
+
+<p>
+ На странице
+<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>
+ Здесь вы можете найти документацию, где представлены подробные сведения о версии Preview:
+</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 Developer Preview, включая информацию об изменениях и различные отчеты.
+ </li>
+</ul>
+
+<h4>
+ Ресурсы поддержки
+</h4>
+
+<p>
+ При тестировании и разработке приложений для M
+Developer Preview рекомендуем пользоваться следующими ресурсами поддержки:
+</p>
+
+<ul>
+ <li><a href="https://code.google.com/p/android-developer-preview/">Система отслеживания проблем M
+Developer Preview</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+, где можно <strong>общаться с другими
+разработчиками</strong>, работающими с Android M. Делитесь в сообществе своими наблюдениями
+и идеями, а также находите ответы на вопросы об Android M.
+ </li>
+</ul>
+
+
+<h2 id="preview_apis_and_publishing">
+ Выбор целевого уровня, предварительные версии API-интерфейсов и публикация приложений
+</h2>
+
+<p>
+ Выпуск Android M Developer Preview предназначен исключительно для разработки и
+<strong>не имеет стандартного уровня API</strong>. Если вы не хотите
+проверять свое приложение на совместимость (хотя мы настоятельно рекомендуем делать это),
+выберите целевой уровень M Developer Preview, задав для параметра <code><a href=
+ "/guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a></code>
+своего приложения значение <code>“MNC”</code>.
+</p>
+
+<p>
+ В Android M Developer Preview представлены <strong>предварительные версии API-интерфейсов</strong>
+&mdash;. Такие API-интерфейсы не будут официально опубликованы до выпуска окончательной версии пакета SDK,
+ намеченого на третий квартал 2015 г. Это означает, что в будущем можно
+<strong>ожидать незначительных изменений в API-интерфейсах</strong>, особенно в
+первые недели действия программы. Каждое обновление
+Android M Developer Preview будет включать обзор изменений.
+</p>
+
+<p class="note">
+ Обратите внимание, что несмотря на возможные изменения в предварительных версиях API-интерфейсов, соответствующие расширения функциональности системы,
+такие как разрешения на выполнение и функции сбережения энергии, работают стабильно и уже готовы для
+тестирования.
+</p>
+
+<p>
+ Что касается публикации приложений, то политика Google Play <strong>однозначно запрещает публикацию приложений,
+разработанных для M Developer Preview</strong>. После выхода окончательной версии пакета SDK Android M
+вы сможете выбрать официальный целевой уровень API Android M и приступить
+к публикации ваших приложений в магазине 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 Preview</a>
+и конфигурированию тестовых устройств.
+ </li>
+
+ <li>Выполните
+<a href="https://developers.google.com/android/nexus/images">инструкции по прошивке</a>, чтобы прошить устройства
+Nexus 5, 6, 9 и Player с использованием последнего системного образа M Developer Preview. После прошивки вашего устройства для разработки
+обновления Preview на него будут приходить по беспроводной сети.</a>
+ </li>
+
+ <li>Загрузите <a href="{@docRoot}preview/download.html#docs">справочник по API-интерфейсам M Preview</a>
+и <a href="{@docRoot}preview/samples.html">примеры кода M Preview</a>
+, чтобы узнать больше о новых возможностях API-интерфейсов и о том, как использовать их в ваших
+приложениях.
+ </li>
+
+ <li>Присоединяйтесь к <a href="http://g.co/dev/AndroidMDevPreview">сообществу разработчиков Android
+M</a>, чтобы всегда быть в курсе последних новостей и общаться с другими
+разработчиками, работающими с новой платформой.
+ </li>
+</ol>
+
+<p>
+ Благодарим за участие в программе Android M Developer!
+</p>
diff --git a/docs/html-intl/intl/ru/training/basics/activity-lifecycle/index.jd b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/index.jd
new file mode 100644
index 0000000..b8de11e
--- /dev/null
+++ b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/index.jd
@@ -0,0 +1,72 @@
+page.title=Управление жизненным циклом операций
+page.tags=жизненный цикл операций
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+
+<h2>Необходимые знания и компоненты</h2>
+<ul>
+ <li>Как создать проект для Android (см. <a href="{@docRoot}training/basics/firstapp/creating-project.html">Создание проекта для Android
+</a>)</li>
+</ul>
+
+
+<h2>См. также:</h2>
+<ul>
+ <li><a href="{@docRoot}guide/components/activities.html">Операции</a></li>
+</ul>
+
+
+<h2>Попробуйте сами</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">Загрузить демонстрацию</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>Во время навигации пользователя по вашему приложению экземпляры
+{@link android.app.Activity} внутри приложения переключаются между разными состояниями их
+жизненного цикла Например, при первом запуске
+операции она получает высокий приоритет в системе и привлекает внимание
+пользователя. Во время этого процесса система Android вызывает серию методов жизненного цикла
+операции, позволяя настроить пользовательский интерфейс и другие компоненты. Если пользователь выполняет
+действие, запускающее другую операцию, или переключается на другое приложение, система вызывает другой набор
+методов жизненного цикла для операции, поскольку она переносится на фоновый уровень (операция больше не
+отображается, но экземпляр и состояние остаются без изменений).</p>
+
+<p>В методах обратного вызова жизненного цикла можно декларировать поведение операции, когда
+пользователь прекращает и снова запускает операцию. Например, если вы разрабатываете проигрыватель потокового видео,
+то можете сделать так, чтобы при переключении пользователя на другое приложение видео ставилось на паузу,
+а сетевое соединение разрывалось. После возврата пользователя проигрыватель может снова подключиться к сети, и пользователь сможет возобновить воспроизведение
+видео с того же самого места.</p>
+
+<p>В этом учебном курсе разъясняются важные методы обратного вызова жизненного цикла, которые получает каждый экземпляр {@link
+android.app.Activity}, и описывается как их использовать, чтобы операция выполнялась так, как этого ожидает
+пользователь, и не потребляла системные ресурсы, когда они ей не нужны.</p>
+
+<h2>Уроки</h2>
+
+<dl>
+ <dt><b><a href="starting.html">Запуск операции</a></b></dt>
+ <dd>Из этого урока вы узнаете об основах жизненного цикла операций, способах запуска вашего приложения пользователями и вариантах
+создания базовых операций.</dd>
+ <dt><b><a href="pausing.html">Приостановка и возобновление операции</a></b></dt>
+ <dd>Вы узнаете, что происходит во время приостановки операции (окно операции частично затемнено) и возобновления операции,
+и что следует делать во время подобных изменений состояния.</dd>
+ <dt><b><a href="stopping.html">Остановка и перезапуск операции</a></b></dt>
+ <dd>В этом уроке рассказывается о том, что происходит, когда пользователь полностью прекращает операцию, а потом возвращается к ней.</dd>
+ <dt><b><a href="recreating.html">Повторное создание операции</a></b></dt>
+ <dd>Вы узнаете, что происходит при полном прекращении операции, и как можно восстановить ее состояние
+в случае необходимости.</dd>
+</dl>
+
diff --git a/docs/html-intl/intl/ru/training/basics/activity-lifecycle/pausing.jd b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/pausing.jd
new file mode 100644
index 0000000..c483780
--- /dev/null
+++ b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/pausing.jd
@@ -0,0 +1,147 @@
+page.title=Приостановка и возобновление операции
+page.tags=жизненный цикл операции
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>Содержание этого урока</h2>
+ <ol>
+ <li><a href="#Pause">Приостановка операции</a></li>
+ <li><a href="#Resume">Возобновление операции</a></li>
+ </ol>
+
+ <h2>См. также:</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">Операции</a>
+ </li>
+ </ul>
+
+<h2>Попробуйте сами</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">Загрузить демонстрацию</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>При обычном использовании приложения выполняемая на экране операция иногда закрывается другими
+визуальными компонентами, в результате чего операция <em>приостанавливается</em>. Например, при открытии полупрозрачной
+операции (например диалогового окна) предыдущая операция приостанавливается. Пока
+операция остается частично видимой, но не остается в фокусе, она остается на паузе.</p>
+
+<p>Однако когда операция полностью закрывается и становится невидимой, она <em>останавливается</em> (об этом будет рассказано
+на следующем уроке).</p>
+
+<p>Когда операция приостанавливается, система вызывает метод {@link
+android.app.Activity#onPause onPause()} на {@link android.app.Activity}, что позволяет
+остановить текущие действия, которые не должны продолжаться во время паузы (например воспроизведение видео), или сохранять
+любую информацию, которая должна постоянно сохраняться в случае выхода пользователя из приложения. Если
+пользователь возвращается к операции после паузы, система возобновляет ее и вызывает метод
+{@link android.app.Activity#onResume onResume()}.</p>
+
+<p class="note"><strong>Примечание.</strong> Когда операция получает вызов {@link
+android.app.Activity#onPause()}, это может указывать, что операция будет приостановлена совсем ненадолго
+и пользователь сможет к ней вернуться. Однако обычно это является первым признаком
+выхода пользователя из операции.</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-paused.png" />
+<p class="img-caption"><strong>Рисунок 1</strong>. Когда полупрозрачная операция закрывает
+вашу операцию, система вызывает {@link android.app.Activity#onPause onPause()} и операция
+переходит в состояние паузы (1). Если пользователь возвращается к операции, находящейся в состоянии паузы,
+система вызывает {@link android.app.Activity#onResume onResume()} (2).</p>
+
+
+<h2 id="Pause">Приостановка операции</h2>
+
+<p>Когда система вызывает {@link android.app.Activity#onPause()} для операции, это
+технически означает, что операция остается частично видимой. Однако чаще всего это означает, что
+пользователь покидает операцию, и вскоре она войдет в состояние остановки. Обратный вызов
+ {@link android.app.Activity#onPause()} обычно следует использовать для следующих целей:</p>
+
+<ul>
+ <li>Остановка анимации или других текущих действий, которые могут потреблять ресурсы процессора.</li>
+ <li>Запись несохраненных изменений, если пользователи ожидают сохранения таких изменений
+при выходе (например черновиков электронных писем).</li>
+ <li>Высвобождение ресурсов системы, например ресиверов, интерфейсов сенсоров (например
+GPS) или других ресурсов, влияющих на время работы аккумулятора во время паузы и не
+требующихся пользователю.</li>
+</ul>
+
+<p>Например, если ваше приложение использует {@link android.hardware.Camera}, метод
+{@link android.app.Activity#onPause()} подойдет для его освобождения.</p>
+
+<pre>
+&#64;Override
+public void onPause() {
+ super.onPause(); // Always call the superclass method first
+
+ // Release the Camera because we don't need it when paused
+ // and other activities might need to use it.
+ if (mCamera != null) {
+ mCamera.release()
+ mCamera = null;
+ }
+}
+</pre>
+
+<p>Обычно <strong>не</strong> следует использовать {@link android.app.Activity#onPause()} для сохранения
+пользовательских изменений (например введенной в форму личной информации) в постоянном хранилище. Изменения
+пользователя нужно сохранять в постоянном хранилище {@link android.app.Activity#onPause()}
+только в тех случаях, когда пользователи ожидают автоматического сохранения изменений (например при составлении черновика электронного письма).
+Однако в состоянии {@link
+android.app.Activity#onPause()} следует избегать операций с высокой нагрузкой на процессор, например выполнения записи в базу данных, поскольку это может замедлить видимый
+переход к следующей операции (вместо этого следует выполнять операции завершения работы с высокой нагрузкой при
+{@link android.app.Activity#onStop onStop()}).</p>
+
+<p>Количество операций, выполняемых с помощью метода {@link android.app.Activity#onPause
+onPause()}, должно быть не очень большим, чтобы пользователь мог быстро переключаться на следующую
+задачу при фактической остановке вашей операции.</p>
+
+<p class="note"><strong>Примечание.</strong> При приостановке операции экземпляр {@link
+android.app.Activity} остается в памяти и заново вызывается при возобновлении операции.
+Не нужно заново инициализировать компоненты, созданные с использованием любого из методов обратного вызова для возобновления
+операции.</p>
+
+
+
+<h2 id="Resume">Возобновление операции</h2>
+
+<p>Когда пользователь возобновляет операцию после паузы, система вызывает метод {@link
+android.app.Activity#onResume()}.</p>
+
+<p>Учтите, что система вызывает этот метод каждый раз, когда ваша операция выполняется на экране,
+в том числе и при первом ее запуске. В связи с этим, нужно реализовать метод {@link
+android.app.Activity#onResume()} для инициализации компонентов, освобождаемых в состоянии {@link
+android.app.Activity#onPause()}, и выполнения других операций инициализации, которые должны происходить каждый раз при возобновлении операции
+(например при запуске анимированных элементов и компонентов, которые используются
+только когда пользователь следит за операцией на экране).</p>
+
+<p>Следующий пример {@link android.app.Activity#onResume()} дополняет
+пример {@link android.app.Activity#onPause()} выше. В нем инициализируется камера,
+которая освобождается на время приостановки операции.</p>
+
+<pre>
+&#64;Override
+public void onResume() {
+ super.onResume(); // Always call the superclass method first
+
+ // Get the Camera instance as the activity achieves full user focus
+ if (mCamera == null) {
+ initializeCamera(); // Local method to handle camera init
+ }
+}
+</pre>
+
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/ru/training/basics/activity-lifecycle/recreating.jd b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/recreating.jd
new file mode 100644
index 0000000..acb89fa
--- /dev/null
+++ b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/recreating.jd
@@ -0,0 +1,178 @@
+page.title=Воссоздание операции
+page.tags=жизненный цикл операции
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>Содержание этого урока</h2>
+ <ol>
+ <li><a href="#SaveState">Сохранение состояния операции</a></li>
+ <li><a href="#RestoreState">Восстановление состояния операции</a></li>
+ </ol>
+
+ <h2>См. также:</h2>
+ <ul>
+ <li><a href="{@docRoot}training/basics/supporting-devices/screens.html">Поддержка
+различных экранов</a></li>
+ <li><a href="{@docRoot}guide/topics/resources/runtime-changes.html">Обработка изменений в режиме выполнения</a></li>
+ <li><a href="{@docRoot}guide/components/activities.html">Операции</a>
+ </li>
+ </ul>
+
+ </div>
+</div>
+
+<p>Существуют ситуации, когда операция уничтожается в результате нормального поведения приложения. Например, это происходит,
+когда пользователь нажимает кнопку <em>Назад</em> или когда операция подает сигнал о своем уничтожении
+посредством вызова {@link android.app.Activity#finish()}. Система также может уничтожить операцию,
+если она остановлена и не используется в течение длительного времени, или если для выполнения операции на экране требуется больше
+системных ресурсов и системе нужно закрыть фоновые процессы для освобождения памяти.</p>
+
+<p>Если операция уничтожается при нажатии пользователем кнопки <em>Назад</em> или завершении
+операции, система считает, что экземпляр {@link android.app.Activity} исчезает навсегда,
+так как такое поведение указывает, что операция больше не нужна. Однако если система уничтожает
+операцию в связи с системными ограничениями (а не в процессе обычной работы приложения), хотя фактический
+{@link android.app.Activity} экземпляр исчезает, система помнит о его существовании, и если
+пользователь вернется к нему, система создаст новый экземпляр действия, используя набор
+сохраненных данных, описывающий состояние операции на момент ее уничтожения. Сохраненные данные, используемые
+системой для восстановления предыдущего состояния, называются "состоянием экземпляра" и представляют собой набор
+пар "ключ-значение", хранящийся в объекте {@link android.os.Bundle}.</p>
+
+<p class="caution"><strong>Внимание!</strong> Ваша операция будет уничтожаться и восстанавливаться каждый раз,
+когда пользователь вращает экран. При изменении ориентации экрана система уничтожает и заново создает
+активную операцию, поскольку конфигурация экрана меняется и операции может потребоваться
+загрузка альтернативных ресурсов (например нового макета).</p>
+
+<p>По умолчанию система использует состояние экземпляра {@link android.os.Bundle} для сохранения информации
+о каждом объекте {@link android.view.View} в макете операции (например, о текстовом значении,
+введенном в объект {@link android.widget.EditText}). Таким образом, если экземпляр вашей операции уничтожается и
+воссоздается заново, происходит восстановление предыдущего состояния макета,
+и при этом вам не нужно добавлять в приложение дополнительный код. Однако операция
+может содержать больше информации о состоянии, чем вы хотите восстановить, например переменные,
+отслеживающие ход выполнения операции пользователем.</p>
+
+<p class="note"><strong>Примечание.</strong> Чтобы система Android могла восстановить состояние
+представлений операции, <strong>каждое представление должно иметь уникальный идентификатор</strong>, предоставляемый атрибутом
+<a href="{@docRoot}reference/android/view/View.html#attr_android:id">{@code
+android:id}</a>.</p>
+
+<p>Для сохранения дополнительных данных о состоянии операции, необходимо
+заменить метод обратного вызова {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}.
+Система вызывает этот метод, когда пользователь покидает операцию,
+и передает ему объект {@link android.os.Bundle}, который будет сохранен в
+случае, если операция будет неожиданно уничтожена. Если
+системе нужно будет воссоздать экземпляр экземпляра операции, она передаст тот же объект {@link
+android.os.Bundle} методам {@link android.app.Activity#onRestoreInstanceState
+onRestoreInstanceState()} и {@link android.app.Activity#onCreate onCreate()}.
+</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-savestate.png" />
+<p class="img-caption"><strong>Рисунок 2</strong>. Когда система начинает останавливать операцию, она
+вызывает {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} (1), чтобы вы могли указать
+дополнительные данные состояния, которые нужно сохранить на случай необходимости воссоздания экземпляра {@link android.app.Activity}.
+Если операция будет уничтожена,
+и системе нужно будет воссоздать тот же экземпляр, она передаст данные
+состояния, определенные в (1), методам {@link android.app.Activity#onCreate onCreate()}
+(2) и {@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}
+(3).</p>
+
+
+
+<h2 id="SaveState">Сохранение состояния операции</h2>
+
+<p>Когда начинается остановка операции, система вызывает метод {@link android.app.Activity#onSaveInstanceState
+onSaveInstanceState()}, чтобы операция могла сохранить информацию о состоянии с помощью набора пар
+"ключ-значение". По умолчанию при реализации этого метода сохраняется информация о состоянии иерархии
+представления операции, например текст в виджете {@link android.widget.EditText} или положение экрана
+для {@link android.widget.ListView}.</p>
+
+<p>Для сохранения дополнительной информации о состоянии операции
+необходимо реализовать {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} и добавить
+к объекту {@link android.os.Bundle} пары "ключ-значение". Например:</p>
+
+<pre>
+static final String STATE_SCORE = "playerScore";
+static final String STATE_LEVEL = "playerLevel";
+...
+
+&#64;Override
+public void onSaveInstanceState(Bundle savedInstanceState) {
+ // Save the user's current game state
+ savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
+ savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
+
+ // Always call the superclass so it can save the view hierarchy state
+ super.onSaveInstanceState(savedInstanceState);
+}
+</pre>
+
+<p class="caution"><strong>Внимание!</strong> Реализацию суперкласса {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()} следует вызывать во всех случаях, чтобы реализация
+по умолчанию могла сохранить состояние новой иерархии.</p>
+
+
+
+<h2 id="RestoreState">Восстановление состояния операции</h2>
+
+<p>В случае воссоздания операции после предыдущего уничтожения сохраненное
+состояние можно восстановить из {@link android.os.Bundle}, куда система
+передает данные операции. Методы обратного вызова {@link android.app.Activity#onCreate onCreate()} и {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} получают один и
+тот же {@link android.os.Bundle}, содержащий информацию о состоянии экземпляра.</p>
+
+<p>Поскольку метод {@link android.app.Activity#onCreate onCreate()} вызывается, если
+система создает новый экземпляр операции или восстанавливает предыдущий экземпляр, перед попыткой чтения необходимо убедиться,
+что {@link android.os.Bundle} имеет состояние null. В этом случае
+система создает новый экземпляр операции
+вместо восстановления ранее уничтоженного экземпляра.</p>
+
+<p>Приведем пример восстановления некоторых данных о состоянии в {@link android.app.Activity#onCreate
+onCreate()}:</p>
+
+<pre>
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState); // Always call the superclass first
+
+ // Check whether we're recreating a previously destroyed instance
+ if (savedInstanceState != null) {
+ // Restore value of members from saved state
+ mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
+ mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
+ } else {
+ // Probably initialize members with default values for a new instance
+ }
+ ...
+}
+</pre>
+
+<p>Вместо восстановления состояния в {@link android.app.Activity#onCreate onCreate()} вы
+можете реализовать метод {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}, который система вызывает
+после метода {@link android.app.Activity#onStart()}. Система вызывает {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} только при наличии сохраненного состояния
+для восстановления, и поэтому вам не нужно проверять, имеет ли {@link android.os.Bundle} значение null:</p>
+
+<pre>
+public void onRestoreInstanceState(Bundle savedInstanceState) {
+ // Always call the superclass so it can restore the view hierarchy
+ super.onRestoreInstanceState(savedInstanceState);
+
+ // Restore state members from saved instance
+ mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
+ mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
+}
+</pre>
+
+<p class="caution"><strong>Внимание!</strong> Реализацию суперкласса {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} следует вызывать во всех случаях, чтобы реализация
+по умолчанию могла сохранить состояние новой иерархии.</p>
+
+<p>Более подробную информацию о воссоздании операции в связи
+с перезапуском во время исполнения (например при повороте экрана) можно найти в разделе <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Обработка изменений в режиме выполнения</a>.</p>
+
diff --git a/docs/html-intl/intl/ru/training/basics/activity-lifecycle/starting.jd b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/starting.jd
new file mode 100644
index 0000000..3a946e2
--- /dev/null
+++ b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/starting.jd
@@ -0,0 +1,285 @@
+page.title=Запуск операции
+page.tags=жизненный цикл операции
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>Содержание этого урока</h2>
+<ol>
+ <li><a href="#lifecycle-states">Изучение обратных вызовов жизненного цикла</a></li>
+ <li><a href="#launching-activity">Указание операции, запускающей приложение</a></li>
+ <li><a href="#Create">Создание нового экземпляра</a></li>
+ <li><a href="#Destroy">Уничтожение операции</a></li>
+</ol>
+
+ <h2>См. также:</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">Операции</a></li>
+ </ul>
+
+<h2>Попробуйте сами</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">Загрузить демонстрацию</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>В отличие от других парадигм программирования, где приложения запускаются с использованием метода {@code main()}, система
+Android запускает код в {@link android.app.Activity}экземпляре посредством активации определенных
+методов обратного вызова, соответствующих определенным этапам его
+жизненного цикла. Существует последовательность методов обратного вызова, которые запускают операцию и последовательность
+методов обратного вызова, уничтожающих операцию.</p>
+
+<p>В этом уроке рассматриваются наиболее важные методы жизненного цикла и демонстрируется, как
+обработать первый обратный вызов жизненного цикла, создающий новый экземпляр операции.</p>
+
+
+
+<h2 id="lifecycle-states">Изучение обратных вызовов жизненного цикла</h2>
+
+<p>В течение цикла существования операции система вызывает базовый набор методов жизненного цикла в
+последовательности, сходной с многоступенчатой пирамидой. Таким образом, каждый этап
+жизненного цикла операции представляет собой отдельную ступень пирамиды. Когда система создает новый экземпляр операции,
+каждый метод обратного вызова перемещает состояние действия на одну ступень вверх. Вершина пирамиды представляет собой
+точку, в которой операция выполняется в экранном режиме, и пользователь может с ней взаимодействовать.</p>
+
+<p>Когда пользователь начинает выходить из операции, система вызывает другие методы, которые перемещают состояние
+операции вниз по пирамиде для уничтожения действия. В некоторых случаях действие
+перемещает операцию вниз по пирамиде только частично и ждет (например когда пользователь переключается на другое приложение),
+а затем операция может быть перемещена обратно вверх (если пользователь вернется к операции) и
+возобновлена там, где пользователь вышел из нее.</p>
+
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle.png" />
+<p class="img-caption"><strong>Рисунок 1</strong>. Упрощенная иллюстрация жизненного цикла операции
+в виде многоступенчатой пирамиды. На рисунке показано, что для каждого обратного вызова,
+поднимающего операцию на одну ступень к состоянию возобновления на вершине пирамиды,
+существует обратный вызов, опускающий операцию на одну ступень вниз. Возобновление операции также может производиться из состояний
+паузы и остановки.</p>
+
+
+<p>В зависимости от сложности операции, некоторые
+методы жизненного цикла могут не требоваться. Однако очень важно понимать все методы и реализовать их так, чтобы
+приложение работало так, как этого ожидают пользователи. Правильная реализация методов жизненного цикла операции
+обеспечивает нормальную работу приложения в нескольких аспектах, в том числе:</p>
+<ul>
+ <li>Не прекращает работу, если пользователь получает телефонный звонок или переключается на другое приложение
+во время использования вашего приложения.</li>
+ <li>Не потребляет ценные системные ресурсы, когда пользователь не использует
+его активно.</li>
+ <li>Сохраняет состояние приложения, если пользователь выходит из него и возвращается
+позднее.</li>
+ <li>Не закрывается с ошибкой и не теряет данные пользователя при повороте экрана (смене ориентации между книжной
+и альбомной.</li>
+</ul>
+
+<!--
+<p class="table-caption"><strong>Table 1.</strong> Activity lifecycle state pairs and callback
+methods.</p>
+<table>
+ <tr>
+ <th scope="col">Lifecycle State</th>
+ <th scope="col">Startup Method</th>
+ <th scope="col">Teardown Method</th>
+ </tr>
+ <tr>
+ <td>Created / Destroyed</td>
+ <td>{@link android.app.Activity#onCreate onCreate()}</td>
+ <td>{@link android.app.Activity#onDestroy()}</td>
+ </tr>
+ <tr>
+ <td>Started / Stopped</td>
+ <td>{@link android.app.Activity#onStart()}</td>
+ <td>{@link android.app.Activity#onStop()}</td>
+ </tr>
+ <tr>
+ <td>Resumed / Resumed</td>
+ <td>{@link android.app.Activity#onResume()}</td>
+ <td>{@link android.app.Activity#onPause()}</td>
+ </tr>
+</table>
+-->
+
+<p>Как вы узнаете на следующих уроках, в некоторых ситуациях операция
+переключается между разными состояниями, как показано на рисунке 1. Однако только три
+из этих состояний могут быть статичными. Это означает, что операция может существовать относительно длительное
+время только в одном из этих трех состояний.</p>
+<dl>
+ <dt>Возобновление</dt>
+ <dd>В этом состоянии операция выполняется в экранном режиме, и пользователь может с ней взаимодействовать.
+Иногда это состояние также называется рабочим состоянием.</dd>
+ <dt>Приостановка</dt>
+ <dd>В этом состоянии операция частично закрывается другой операцией &mdash; в экранном режиме
+эта другая операция или является полупрозрачной, или не закрывает экран целиком. Приостановленная операция
+не получает команд пользователя и не может выполнять код.
+ <dt>Остановка</dt>
+ <dd>В этом состоянии операция полностью скрыта и невидима для пользователя. Она считается находящейся в
+фоновом режиме. В состоянии остановки сохраняется экземпляр операции и вся его информация
+о состоянии, например, переменных, однако операция не может выполнять код.</dd>
+</dl>
+
+<p>Другие состояния (создание и запуск) являются переходными, и система быстро переходит от них
+к следующим состояниям посредством вызова следующего метода обратного вызова в жизненном цикле. Таким образом, после вызова
+{@link android.app.Activity#onCreate onCreate()} система быстро вызывает {@link
+android.app.Activity#onStart()}, а затем сразу же вызывает {@link
+android.app.Activity#onResume()}.</p>
+
+<p>Так выглядит базовый жизненный цикл операции. Теперь рассмотрим определенные виды
+поведения в жизненном цикле.</p>
+
+
+
+<h2 id="launching-activity">Указание операции, запускающей приложение</h2>
+
+<p>Когда пользователь выбирает значок приложения на главном экране, система вызывает метод {@link
+android.app.Activity#onCreate onCreate()} для {@link android.app.Activity} в вашем приложении
+в соответствии с тем, какую операцию вы задекларировали как операцию запуска (или основную операцию). Эта операция выступает
+основной точкой входа в пользовательский интерфейс вашего приложения.</p>
+
+<p>Для определения основной операции вы можете использовать файл манифеста Android <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">{@code AndroidManifest.xml}</a>,
+который находится в корневом каталоге вашего проекта.</p>
+
+<p>Основная операция приложения должна декларироваться в манифесте с помощью фильтра <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a>, включающего действие {@link
+android.content.Intent#ACTION_MAIN MAIN} и категорию
+{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER}. Например:</p>
+
+<pre>
+&lt;activity android:name=".MainActivity" android:label="&#64;string/app_name">
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.MAIN" />
+ &lt;category android:name="android.intent.category.LAUNCHER" />
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p class="note"><strong>Примечание.</strong> При создании нового проекта Android с помощью инструментов
+Android SDK файлы проекта по умолчанию включают класс {@link android.app.Activity}, который декларируется в
+манифесте с помощью этого фильтра.</p>
+
+<p>Если для одной из операций не декларировано действие {@link android.content.Intent#ACTION_MAIN MAIN} или категория
+{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER}, значок
+приложения не будет отображатья в списке приложений на главном экране.</p>
+
+
+
+<h2 id="Create">Создание нового экземпляра</h2>
+
+<p>Большинство приложений содержат различные операции, позволяющие пользователю выполнять различные действия.
+Как для основных операций, создаваемых при нажатии на значок приложения, так
+и для других операций, которыми приложение реагирует на действия пользователя, система создает
+каждый новый экземпляр {@link android.app.Activity} посредством вызова его метода {@link
+android.app.Activity#onCreate onCreate()}.</p>
+
+<p>Вы должны реализовать метод {@link android.app.Activity#onCreate onCreate()} для выполнения базовой
+логики запуска приложения, которое должно производиться только один раз для всего срока существования операции. Например,
+ваша реализация {@link android.app.Activity#onCreate onCreate()} должна содержать определение пользовательского
+интерфейса и возможно создавать экземпляры некоторых переменных уровня класса.</p>
+
+<p>Например, в следующем примере метода {@link android.app.Activity#onCreate onCreate()}
+показан код, выполняющий фундаментальную настройку операции, включая
+декларирование пользовательского интерфейса (определен в файле макета XML), определение составных переменных
+и частичную настройку пользовательского интерфейса.</p>
+
+<pre>
+TextView mTextView; // Member variable for text view in the layout
+
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Set the user interface layout for this Activity
+ // The layout file is defined in the project res/layout/main_activity.xml file
+ setContentView(R.layout.main_activity);
+
+ // Initialize member TextView so we can manipulate it later
+ mTextView = (TextView) findViewById(R.id.text_message);
+
+ // Make sure we're running on Honeycomb or higher to use ActionBar APIs
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ // For the main activity, make sure the app icon in the action bar
+ // does not behave as a button
+ ActionBar actionBar = getActionBar();
+ actionBar.setHomeButtonEnabled(false);
+ }
+}
+</pre>
+
+<p class="caution"><strong>Внимание!</strong> Использование {@link android.os.Build.VERSION#SDK_INT} для
+предотвращения запуска новых API-интерфейсов на старых системах поддерживается только в Android версии 2.0 (API-интерфейсы уровня
+5) и более поздних версиях. В старых версиях возникнет ошибка времени исполнения.</p>
+
+<p>После завершения выполнения {@link android.app.Activity#onCreate onCreate()} система
+быстро вызывает методы {@link android.app.Activity#onStart()} и {@link android.app.Activity#onResume()} по
+очереди. Операция никогда не остается в состоянии создания или запуска. Технически
+операция становится видимой для пользователя при вызове {@link android.app.Activity#onStart()}, однако затем сразу же происходит
+{@link android.app.Activity#onResume()} и операция остается в состоянии возобновления,
+пока что-то не произойдет, например пока не поступит телефонный звонок, пользователь не переключится
+на другую операцию или экран устройства не выключится.</p>
+
+<p>На последующих уроках вы увидите, как можно с пользой использовать другие методы запуска, {@link
+android.app.Activity#onStart()} и {@link android.app.Activity#onResume()}, в жизненном цикле операции
+при возобновлении работы после паузы или остановки.</p>
+
+<p class="note"><strong>Примечание.</strong> Метод {@link android.app.Activity#onCreate onCreate()}
+включает параметр <code>savedInstanceState</code>, о котором будет рассказано на
+уроке <a href="recreating.html">Воссоздание операции</a>.</p>
+
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-create.png" />
+<p class="img-caption"><strong>Рисунок 2.</strong> Еще один пример структуры жизненного
+цикла операции, где основное внимание трем главным обратным вызовам, которые система выполняет по очереди при создании
+нового экземпляра операции: {@link android.app.Activity#onCreate onCreate()}, {@link
+android.app.Activity#onStart()} и {@link android.app.Activity#onResume()}. После завершения этой серии
+обратных вызовов операция переходит в состояние возобновления, где пользователи могут
+взаимодействовать с операцией до тех пор, пока не переключатся на другую операцию.</p>
+
+
+
+
+
+
+
+<h2 id="Destroy">Уничтожение операции</h2>
+
+<p>Первым обратным вызовом жизненного цикла операции является {@link android.app.Activity#onCreate
+onCreate()}, а последним – {@link android.app.Activity#onDestroy}. Система вызывает
+этот метод для операции, подавая окончательный сигнал
+о том, что экземпляр операции полностью удаляется из системной памяти.</p>
+
+<p>Большинству приложений не требуется реализация этого метода, потому что ссылки локальных классов уничтожаются
+вместе с операцией, а основные задачи по освобождению ресурсов операция выполняет в состояниях {@link
+android.app.Activity#onPause} и {@link android.app.Activity#onStop}. Однако если ваша
+операция содержит фоновые потоки, созданные во время выполнения {@link
+android.app.Activity#onCreate onCreate()}, или в течение длительного времени использует другие ресурсы, могущие
+вызывать утечку памяти при неправильном закрытии, их нужно уничтожить с помощью метода {@link
+android.app.Activity#onDestroy}.</p>
+
+<pre>
+&#64;Override
+public void onDestroy() {
+ super.onDestroy(); // Always call the superclass
+
+ // Stop method tracing that the activity started during onCreate()
+ android.os.Debug.stopMethodTracing();
+}
+</pre>
+
+<p class="note"><strong>Примечание.</strong> Система вызывает {@link android.app.Activity#onDestroy}
+после вызова {@link android.app.Activity#onPause} и {@link
+android.app.Activity#onStop} во всех случаях, кроме ситуации, когда вы вызываете {@link
+android.app.Activity#finish()} из метода {@link android.app.Activity#onCreate onCreate()}
+. В некоторых случаях, например когда ваша операция временно отвечает за принятие решения о запуске
+другой операции, вы можете вызвать {@link android.app.Activity#finish()} из метода {@link
+android.app.Activity#onCreate onCreate()} для уничтожения операции. В этом случае система
+сразу же вызывает {@link android.app.Activity#onDestroy}, не вызывая другие методы жизненного
+цикла.</p>
diff --git a/docs/html-intl/intl/ru/training/basics/activity-lifecycle/stopping.jd b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/stopping.jd
new file mode 100644
index 0000000..27c771f
--- /dev/null
+++ b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/stopping.jd
@@ -0,0 +1,187 @@
+page.title=Остановка и перезапуск операции
+page.tags=жизненный цикл операции
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>Содержание этого урока</h2>
+ <ol>
+ <li><a href="#Stop">Остановка операции</a></li>
+ <li><a href="#Start">Запуск/перезапуск операции</a></li>
+ </ol>
+
+ <h2>См. также:</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">Операции</a>
+ </li>
+ </ul>
+
+<h2>Попробуйте сами</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">Загрузить демонстрацию</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>Правильное выполнение остановки и перезапуска операции является важным шагом в жизненном
+цикле операции, благодаря которому пользователи понимают, что приложение не потеряет их данные.
+Ниже приведен пример нескольких основных ситуаций с остановкой и перезапуском операции.</p>
+
+<ul>
+ <li>Пользователь открывает окно "Последние приложения" и переключается из вашего приложения в другое приложение.
+При этом останавливается операция вашего приложения, работающего на экране. Если пользователь возвращается в ваше
+приложение, нажав значок запуска на главном экране или через окно "Последние приложения", данная операция возобновляется.</li>
+ <li>Пользователь выполняет в вашем приложении действие, запускающее новую операцию. Текущая операция
+останавливается при создании второй операции. Если после этого пользователь нажимает кнопку <em>Назад</em>
+, первая операция запускается заново.</li>
+ <li>Пользователь получает телефонный звонок или переключается на другое приложение во время использования вашего приложения на своем телефоне.</li>
+</ul>
+
+<p>Класс {@link android.app.Activity} предоставляет два метода жизненного цикла, {@link
+android.app.Activity#onStop()} и {@link android.app.Activity#onRestart()}, позволяющие явно
+обрабатывать остановку и перезапуск операции. В отличие от состояния паузы,
+означающем частичное уничтожение пользовательского интерфейса, в состоянии остановки пользовательский интерфейс больше не
+отображается и пользователь переключается на отдельную операцию (или отдельное приложение).</p>
+
+<p class="note"><strong>Примечание.</strong> Поскольку система хранит ваш экземпляр {@link android.app.Activity}
+в системной памяти при остановке, вам, возможно, вообще не потребуется реализация методов
+{@link android.app.Activity#onStop()} и {@link android.app.Activity#onRestart()} (или даже {@link
+android.app.Activity#onStart()}. Большинство операций относительно простые, и операция
+остановится и перезапустится нормально, вам только может потребоваться {@link
+android.app.Activity#onPause()} для приостановки текущих операций и отключения от системных ресурсов.</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-stopped.png" />
+<p class="img-caption"><strong>Рисунок 1.</strong> Когда пользователь выйдет из операции, система
+вызовет {@link android.app.Activity#onStop onStop()} для остановки операции (1). Если пользователь возвращается
+при остановке операции, система вызывает {@link android.app.Activity#onRestart onRestart()}
+(2), затем сразу же {@link android.app.Activity#onStart onStart()} (3) и {@link
+android.app.Activity#onResume()} (4). Вне зависимости от причины остановки
+операции, система всегда вызывает {@link android.app.Activity#onPause onPause()} перед вызовом {@link
+android.app.Activity#onStop onStop()}.</p>
+
+
+
+<h2 id="Stop">Остановка операции</h2>
+
+<p>Когда операция получает вызов метода {@link android.app.Activity#onStop()},
+она становится невидимой и освобождает практически все ресурсы, которые не нужны ей, когда пользователь ее не
+использует. После остановки операции система может уничтожить экземпляр, если ей потребуется
+освободить системную память. В чрезвычайных ситуациях система может закрыть процесс приложения без
+вызова последнего метода обратного вызова {@link android.app.Activity#onDestroy()} операции, и поэтому важно
+использовать {@link android.app.Activity#onStop()} для высвобождения ресурсов, которые могут вызвать утечку памяти.</p>
+
+<p>Хотя метод {@link android.app.Activity#onPause onPause()} вызывается до
+{@link android.app.Activity#onStop()}, вам следует использовать {@link android.app.Activity#onStop onStop()}
+для выполнения более масштабных операций выключения с использованием процессорных ресурсов, например при записи информации в базу
+данных.</p>
+
+<p>В качестве примера приведем реализацию {@link android.app.Activity#onStop onStop()},
+сохраняющую содержание черновой заметки в постоянное хранилище:</p>
+
+<!-- TODO: Find a better example for onStop, because this kind of thing should probably use a
+separate thread but that's too complicated to show here. -->
+<pre>
+&#64;Override
+protected void onStop() {
+ super.onStop(); // Always call the superclass method first
+
+ // Save the note's current draft, because the activity is stopping
+ // and we want to be sure the current note progress isn't lost.
+ ContentValues values = new ContentValues();
+ values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
+ values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());
+
+ getContentResolver().update(
+ mUri, // The URI for the note to update.
+ values, // The map of column names and new values to apply to them.
+ null, // No SELECT criteria are used.
+ null // No WHERE columns are used.
+ );
+}
+</pre>
+
+<p>При остановке операции объект {@link android.app.Activity} остается в памяти
+и вызывается повторно при возобновлении операции. Не нужно заново инициализировать компоненты,
+созданные с использованием любого из методов обратного вызова для возобновления операции. Система также
+отслеживает текущее состояние каждого {@link android.view.View} в макете, и если
+пользователь вводит текст в виджет {@link android.widget.EditText}, этот текст сохраняется, так что его не
+нужно специально сохранять и восстанавливать.</p>
+
+<p class="note"><strong>Примечание.</strong> Даже если система уничтожит операцию в период остановки,
+она сохранит состояние объектов {@link android.view.View} (например, текста в {@link
+android.widget.EditText}) в {@link android.os.Bundle} (наборе пар "ключ-значение") и восстановит
+их, если пользователь вернется в тот же экземпляр операции (на <a href="recreating.html">следующем уроке</a> мы более подробно поговорим об использовании {@link android.os.Bundle} для сохранения
+других данных состояния в случае уничтожения и воссоздания вашей операции).</p>
+
+
+
+<h2 id="Start">Запуск/перезапуск операции</h2>
+
+<p>Когда ваша операция возвращается в экранный режим из состояния остановки, она получает вызов
+{@link android.app.Activity#onRestart()}. Система также вызывает метод {@link
+android.app.Activity#onStart()}, что происходит каждый раз, когда операция становится видимой
+(при перезапуске или первоначальном создании). Однако метод {@link
+android.app.Activity#onRestart()} вызывается только при возобновлении операции из состояния
+остановки, так что его можно использовать для выполнения специальных задач восстановления, которые могут требоваться только если операция
+была остановлена, но не была уничтожена.</p>
+
+<p>Приложениям редко требуется использовать {@link android.app.Activity#onRestart()} для восстановления
+состояния операции, и поэтому для этого метода нет правил, относящихся
+к обычным приложениям. Однако поскольку ваш метод {@link android.app.Activity#onStop()}
+должен фактически освободить все ресурсы операции, их нужно снова выделить
+при перезапуске операции. Однако их также нужно выделять при первом
+создании операции (когда нет существующего экземпляра операции). По этому причине обычно
+используют метод обратного вызова {@link android.app.Activity#onStart()} в дополнение
+к методу {@link android.app.Activity#onStop()}, поскольку система вызывает {@link
+android.app.Activity#onStart()} как при создании операции, так и при ее перезапуске
+после остановки.</p>
+
+<p>Например, если пользователь долго не пользовался приложением,
+а затем вернулся в него, метод {@link android.app.Activity#onStart()} хорошо помогает убедиться, что требуемые
+системные функции включены:</p>
+
+<pre>
+&#64;Override
+protected void onStart() {
+ super.onStart(); // Always call the superclass method first
+
+ // The activity is either being restarted or started for the first time
+ // so this is where we should make sure that GPS is enabled
+ LocationManager locationManager =
+ (LocationManager) getSystemService(Context.LOCATION_SERVICE);
+ boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
+
+ if (!gpsEnabled) {
+ // Create a dialog here that requests the user to enable GPS, and use an intent
+ // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action
+ // to take the user to the Settings screen to enable GPS when they click "OK"
+ }
+}
+
+&#64;Override
+protected void onRestart() {
+ super.onRestart(); // Always call the superclass method first
+
+ // Activity being restarted from stopped state
+}
+</pre>
+
+
+
+
+<p>Когда система уничтожает вашу операцию, она вызывает метод {@link android.app.Activity#onDestroy()}
+для вашего {@link android.app.Activity}. Поскольку вы уже освобождаете большую часть
+ресурсов с помощью {@link android.app.Activity#onStop()} к моменту вызова {@link
+android.app.Activity#onDestroy()}, большинству приложений почти ничего не нужно делать. Этот метод представляет собой последний
+шанс освободить ресурсы, могущие привести к утечке памяти, обеспечивая уверенность
+в уничтожении дополнительных потоков и других долгосрочных действий, например, отслеживания
+методов.</p>
+
diff --git a/docs/html-intl/intl/ru/training/basics/data-storage/databases.jd b/docs/html-intl/intl/ru/training/basics/data-storage/databases.jd
new file mode 100644
index 0000000..418d288
--- /dev/null
+++ b/docs/html-intl/intl/ru/training/basics/data-storage/databases.jd
@@ -0,0 +1,317 @@
+page.title=Сохранение данных в базах данных SQL
+page.tags=хранение данных
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Содержание этого урока</h2>
+<ol>
+ <li><a href="#DefineContract">Определение схемы и контракта</a></li>
+ <li><a href="#DbHelper">Создание базы данных с помощью SQL Helper</a></li>
+ <li><a href="#WriteDbRow">Размещение информации в базе данных</a></li>
+ <li><a href="#ReadDbRow">Чтение информации из базы данных</a></li>
+ <li><a href="#DeleteDbRow">Удаление информации из базы данных</a></li>
+ <li><a href="#UpdateDbRow">Обновление базы данных</a></li>
+</ol>
+
+<h2>См. также:</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#db">Использование баз данных</a></li>
+</ul>
+
+<!--
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/Sample.zip" class="button">Download the sample</a>
+ <p class="filename">Sample.zip</p>
+</div>
+-->
+
+</div>
+</div>
+
+
+<p>Сохранение данных в базе идеально подходит для повторяющихся и структурированных данных,
+таких как контактная информация. В этом учебном курсе предполагается, что вы
+владеете общими знаниями о базах данных SQL, и он поможет вам начать работать с базами данных
+SQLite на платформе Android. API-интерфейсы, необходимые для использования базы данных
+на платформе Android, доступны в составе пакета {@link android.database.sqlite}.</p>
+
+
+<h2 id="DefineContract">Определение схемы и контракта</h2>
+
+<p>Одним из основных элементов баз данных SQL является схема, которая представляет собой формальную
+декларацию способа организации базы данных. Схема отражается в выражениях SQL,
+используемых для создания базы данных. Для вас может оказаться полезным
+создать сопутствующий класс (<em>класс-контракт</em>), явно указывающий структуру
+схемы систематическим и самодокументирующим способом.</p>
+
+<p>Класс-контракт представляет собой контейнер, определяющий имена для URI-адресов,
+таблиц и столбцов. Класс-контракт позволяет использовать одни и те же постоянные значения
+во всех других классах этого же пакета. Таким образом, при изменении имени
+столбца в одном месте это изменение применяется во всем коде.</p>
+
+<p>Для удобства организации класс-контракта стоит поместить
+глобальные определения базы данных на корневой уровень класса. Затем нужно создать внутренний
+класс для каждой таблицы, производящей нумерацию столбцов.</p>
+
+<p class="note"><strong>Примечание.</strong> За счет реализации интерфейса {@link
+android.provider.BaseColumns} внутренний класс может наследовать поле первичного
+ключа {@code _ID}, наличия которого ожидают от него некоторые
+классы Android (например, адаптеры курсора). Это не является обязательным условием, однако может помочь обеспечить гармоничную работу
+вашей базы данных в инфраструктуре Android.</p>
+
+<p>Например, в этом фрагменте кода определяются имя таблицы и имена столбцов для
+одной таблицы:</p>
+
+
+<pre>
+public final class FeedReaderContract {
+ // To prevent someone from accidentally instantiating the contract class,
+ // give it an empty constructor.
+ public FeedReaderContract() {}
+
+ /* Inner class that defines the table contents */
+ public static abstract class FeedEntry implements BaseColumns {
+ public static final String TABLE_NAME = &quot;entry&quot;;
+ public static final String COLUMN_NAME_ENTRY_ID = &quot;entryid&quot;;
+ public static final String COLUMN_NAME_TITLE = &quot;title&quot;;
+ public static final String COLUMN_NAME_SUBTITLE = &quot;subtitle&quot;;
+ ...
+ }
+}
+</pre>
+
+
+
+<h2 id="DbHelper">Создание базы данных с помощью SQL Helper</h2>
+
+<p>После определения внешнего вида базы данных следует реализовать методы
+создания и обслуживания базы данных и таблиц. Вот некоторые типичные
+выражения для создания и удаления таблиц:</P>
+
+<pre>
+private static final String TEXT_TYPE = &quot; TEXT&quot;;
+private static final String COMMA_SEP = &quot;,&quot;;
+private static final String SQL_CREATE_ENTRIES =
+ &quot;CREATE TABLE &quot; + FeedEntry.TABLE_NAME + &quot; (&quot; +
+ FeedEntry._ID + &quot; INTEGER PRIMARY KEY,&quot; +
+ FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP +
+ FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
+ ... // Any other options for the CREATE command
+ &quot; )&quot;;
+
+private static final String SQL_DELETE_ENTRIES =
+ &quot;DROP TABLE IF EXISTS &quot; + FeedEntry.TABLE_NAME;
+</pre>
+
+<p>Как и при сохранении файлов во <a href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">внутренней
+памяти</a> устройства, Android сохраняет вашу базу данных в закрытой области диска, связанной
+с приложением Эти данные защищены, потому что эта область
+по умолчанию недоступна другим приложениям.</p>
+
+<p>Полезный набор API-интерфейсов содержится в классе {@link
+android.database.sqlite.SQLiteOpenHelper}.
+Если вы используете этот класс для получения ссылок на свою базу данных, система
+выполняет потенциально
+долговременные операции создания и обновления базы данных только тогда, когда это
+необходимо, а <em>не при запуске приложения</em>. Для этого нужно использовать вызов
+{@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase} или
+{@link android.database.sqlite.SQLiteOpenHelper#getReadableDatabase}.</p>
+
+<p class="note"><strong>Примечание.</strong> Поскольку операции могут выполняться длительное время,
+вызывайте {@link
+android.database.sqlite.SQLiteOpenHelper#getWritableDatabase} или {@link
+android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} в фоновом потоке,
+например с {@link android.os.AsyncTask} или {@link android.app.IntentService}.</p>
+
+<p>Для использования {@link android.database.sqlite.SQLiteOpenHelper} создайте подкласс, заменяющий методы
+вызова {@link
+android.database.sqlite.SQLiteOpenHelper#onCreate onCreate()}, {@link
+android.database.sqlite.SQLiteOpenHelper#onUpgrade onUpgrade()} и {@link
+android.database.sqlite.SQLiteOpenHelper#onOpen onOpen()}. Также вы можете
+использовать {@link android.database.sqlite.SQLiteOpenHelper#onDowngrade onDowngrade()},
+но это не требуется.</p>
+
+<p>Например, вот реализация {@link
+android.database.sqlite.SQLiteOpenHelper}, при которой используются некоторые из приведенных выше команд:</p>
+
+<pre>
+public class FeedReaderDbHelper extends SQLiteOpenHelper {
+ // If you change the database schema, you must increment the database version.
+ public static final int DATABASE_VERSION = 1;
+ public static final String DATABASE_NAME = &quot;FeedReader.db&quot;;
+
+ public FeedReaderDbHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL(SQL_CREATE_ENTRIES);
+ }
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // This database is only a cache for online data, so its upgrade policy is
+ // to simply to discard the data and start over
+ db.execSQL(SQL_DELETE_ENTRIES);
+ onCreate(db);
+ }
+ public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ onUpgrade(db, oldVersion, newVersion);
+ }
+}
+</pre>
+
+<p>Для получения доступа к базе данных создайте экземпляр подкласса {@link
+android.database.sqlite.SQLiteOpenHelper}:</p>
+
+<pre>
+FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());
+</pre>
+
+
+
+
+<h2 id="WriteDbRow">Размещение информации в базе данных</h2>
+
+<p>Добавьте данные в базу данных, передав объект {@link android.content.ContentValues}
+в метод {@link android.database.sqlite.SQLiteDatabase#insert insert()}:</p>
+
+<pre>
+// Gets the data repository in write mode
+SQLiteDatabase db = mDbHelper.getWritableDatabase();
+
+// Create a new map of values, where column names are the keys
+ContentValues values = new ContentValues();
+values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id);
+values.put(FeedEntry.COLUMN_NAME_TITLE, title);
+values.put(FeedEntry.COLUMN_NAME_CONTENT, content);
+
+// Insert the new row, returning the primary key value of the new row
+long newRowId;
+newRowId = db.insert(
+ FeedEntry.TABLE_NAME,
+ FeedEntry.COLUMN_NAME_NULLABLE,
+ values);
+</pre>
+
+<p>Первый аргумент {@link android.database.sqlite.SQLiteDatabase#insert insert()}
+представляет собой просто название таблицы. Второй аргумент указывает
+имя столбца, в который инфраструктура вставляет значение NULL, если
+{@link android.content.ContentValues} является пустым (если вместо этого указать {@code "null"},
+то инфраструктура не будет вставлять строку в случае отсутствия значений).</p>
+
+
+
+
+<h2 id="ReadDbRow">Чтение информации из базы данных</h2>
+
+<p>Для чтения из базы данных используйте метод {@link android.database.sqlite.SQLiteDatabase#query query()}
+с передачей критериев выделения и желаемых столбцов.
+Метод сочетает элементы {@link android.database.sqlite.SQLiteDatabase#insert insert()}
+и {@link android.database.sqlite.SQLiteDatabase#update update()}, за исключением того, что список столбцов
+определяет данные, которые вы хотите получить, а не данные для вставки. Результаты запроса
+возвращаются в объекте {@link android.database.Cursor}.</p>
+
+<pre>
+SQLiteDatabase db = mDbHelper.getReadableDatabase();
+
+// Define a <em>projection</em> that specifies which columns from the database
+// you will actually use after this query.
+String[] projection = {
+ FeedEntry._ID,
+ FeedEntry.COLUMN_NAME_TITLE,
+ FeedEntry.COLUMN_NAME_UPDATED,
+ ...
+ };
+
+// How you want the results sorted in the resulting Cursor
+String sortOrder =
+ FeedEntry.COLUMN_NAME_UPDATED + " DESC";
+
+Cursor c = db.query(
+ FeedEntry.TABLE_NAME, // The table to query
+ projection, // The columns to return
+ selection, // The columns for the WHERE clause
+ selectionArgs, // The values for the WHERE clause
+ null, // don't group the rows
+ null, // don't filter by row groups
+ sortOrder // The sort order
+ );
+</pre>
+
+<p>Чтобы посмотреть на строку в месте курсора, используйте один из методов перемещения
+{@link android.database.Cursor}, которые всегда нужно вызывать перед считыванием значений. Обычно следует начинать
+с вызова {@link android.database.Cursor#moveToFirst}, который помещает "позицию чтения"
+на первую запись в результатах. Для каждой строки значение столбца можно прочитать, вызвав один из методов
+{@link android.database.Cursor} get, например {@link android.database.Cursor#getString
+getString()} или {@link android.database.Cursor#getLong getLong()}. Для каждого из методов get
+вы должны передать указатель желаемого столбца, который может вызвать
+{@link android.database.Cursor#getColumnIndex getColumnIndex()} или
+{@link android.database.Cursor#getColumnIndexOrThrow getColumnIndexOrThrow()}.
+Например:</p>
+
+<pre>
+cursor.moveToFirst();
+long itemId = cursor.getLong(
+ cursor.getColumnIndexOrThrow(FeedEntry._ID)
+);
+</pre>
+
+
+
+
+<h2 id="DeleteDbRow">Удаление информации из базы данных</h2>
+
+<p>Для удаления строк из таблицы нужно указать критерии выделения,
+идентифицирующие строки. API-интерфейс базы данных обеспечивает механизм для создания критериев
+выделения, предоставляющий защиту от внедрения SQL-кода. Механизм делит спецификацию выбора
+на предложение выбора и аргументы выбора. Предложение
+определяет столбцы для рассмотрения, а также позволяет объединять операции тестирования
+столбцов. Аргументы представляют собой значения для тестирования, которые привязаны к пункту.
+Поскольку результат обрабатывается не как обычные выражения SQL,
+он защищен от внедрения SQL-кода.</p>
+
+<pre>
+// Define 'where' part of query.
+String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + &quot; LIKE ?&quot;;
+// Specify arguments in placeholder order.
+String[] selectionArgs = { String.valueOf(rowId) };
+// Issue SQL statement.
+db.delete(table_name, selection, selectionArgs);
+</pre>
+
+
+
+<h2 id="UpdateDbRow">Обновление базы данных</h2>
+
+<p>При необходимости изменить набор значений базы данных используйте метод {@link
+android.database.sqlite.SQLiteDatabase#update update()}.</p>
+
+<p>Обновление таблицы сочетает значения синтаксиса {@link
+android.database.sqlite.SQLiteDatabase#insert insert()} и синтаксиса {@code where}
+для {@link android.database.sqlite.SQLiteDatabase#delete delete()}.</p>
+
+<pre>
+SQLiteDatabase db = mDbHelper.getReadableDatabase();
+
+// New value for one column
+ContentValues values = new ContentValues();
+values.put(FeedEntry.COLUMN_NAME_TITLE, title);
+
+// Which row to update, based on the ID
+String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + &quot; LIKE ?&quot;;
+String[] selectionArgs = { String.valueOf(rowId) };
+
+int count = db.update(
+ FeedReaderDbHelper.FeedEntry.TABLE_NAME,
+ values,
+ selection,
+ selectionArgs);
+</pre>
+
diff --git a/docs/html-intl/intl/ru/training/basics/data-storage/files.jd b/docs/html-intl/intl/ru/training/basics/data-storage/files.jd
new file mode 100644
index 0000000..2afecea
--- /dev/null
+++ b/docs/html-intl/intl/ru/training/basics/data-storage/files.jd
@@ -0,0 +1,379 @@
+page.title=Сохранение файлов
+page.tags=хранение данных
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Содержание этого урока</h2>
+<ol>
+ <li><a href="#InternalVsExternalStorage">Выбор внутреннего или внешнего хранилища</a></li>
+ <li><a href="#GetWritePermission">Получение разрешений на доступ к внешнему хранилищу</a></li>
+ <li><a href="#WriteInternalStorage">Сохранение файла во внутреннем хранилище</a></li>
+ <li><a href="#WriteExternalStorage">Сохранение файла во внешнем хранилище</a></li>
+ <li><a href="#GetFreeSpace">Запрос свободного пространства</a></li>
+ <li><a href="#DeleteFile">Удаление файла</a></li>
+</ol>
+
+<h2>См. также:</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">Использование внутреннего
+хранилища</a></li>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#filesExternal">Использование внешнего
+хранилища</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>Операционная система Android использует файловую систему,
+похожую на дисковые файловые системы других платформ. В этом уроке рассказывается,
+как работать с файловой системой Android для чтения и записи файлов в {@link java.io.File}
+API-интерфейсах.</p>
+
+<p>Объект {@link java.io.File} подходит для чтения или записи больших объемов данных в порядке
+от начала к концу без пропусков. Например, этот способ оптимален для изображений или
+любых других файлов, передаваемых по сети.</p>
+
+<p>В этом уроке вы узнаете, как выполнять в приложении базовые задачи, связанные с файлами.
+Для прохождения урока вы должны быть знакомы с основами файловой системы Linux
+и стандартными файловыми API-интерфейсами ввода/вывода в {@link java.io}.</p>
+
+
+<h2 id="InternalVsExternalStorage">Выбор внутреннего или внешнего хранилища</h2>
+
+<p>Все устройства Android имеют две области хранения файлов: внутренняя память и внешние хранилища. Эти области
+появились в первые годы существования Android, когда на большинстве устройств имелись встроенная память
+(внутреннее хранилище) и карты памяти (например micro SD, внешнее хранилище).
+Некоторые устройства делят встроенную память на внутренний и внешний разделы,
+так что даже без съемных носителей в системе две области хранения файлов,
+и API-интерфейс работает одинаково вне зависимости от типа внешнего хранилища.
+Ниже подробно описаны обе области хранения файлов.</p>
+
+<div class="col-5" style="margin-left:0">
+<p><b>Внутренняя память</b></p>
+<ul>
+<li>Всегда доступна.</li>
+<li>Сохраненные здесь файлы по умолчанию доступны только вашему приложению.</li>
+<li>При удалении пользователем вашего приложения система Android удаляет из внутренней памяти
+все файлы этого приложения.</li>
+</ul>
+<p>Внутренняя память лучше всего подходит для ситуаций, когда вы хотите быть уверены, что ни пользователь, ни другие приложения не смогут получить
+доступ к вашим файлам.</p>
+</div>
+
+<div class="col-7" style="margin-right:0">
+<p><b>Внешнее хранилище</b></p>
+<ul>
+<li>Доступно не всегда, потому что пользователь может в любое время подключать и отключать такие
+хранилища, например, USB-накопители.</li>
+<li>Такие хранилища доступны для чтения везде,
+поэтому вы не контролируете чтение сохраненных в них данных.</li>
+<li>При удалении пользователем вашего приложения система Android удаляет из внешних хранилищ
+файлы этого приложения, только если они сохраняются в директории из {@link android.content.Context#getExternalFilesDir
+getExternalFilesDir()}.</li>
+</ul>
+<p>Внешнее хранилище лучше всего
+подходит для файлов без ограничений доступа и для файлов, которые вы хотите сделать
+доступными другим приложениям или пользователю через компьютер.</p>
+</div>
+
+
+<p class="note" style="clear:both">
+<strong>Совет.</strong> Хотя по умолчанию приложения устанавливаются во внутреннюю память,
+вы можете указать в манифесте атрибут <a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code
+android:installLocation}</a>, чтобы приложение можно
+было установить во внешнее хранилище. Этот вариант будет полезен пользователям при большом размере файла APK, либо если у них есть доступ
+к внешнему хранилищу, объем которого превышает внутреннюю память. Дополнительную информацию
+см. в разделе <a href="{@docRoot}guide/topics/data/install-location.html">Место установки приложения</a>.</p>
+
+
+<h2 id="GetWritePermission">Получение разрешений доступа к внешнему хранилищу</h2>
+
+<p>Для записи во внешнее хранилище следует указать запрос
+разрешения {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} в <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">файле манифеста</a>:</p>
+
+<pre>
+&lt;manifest ...>
+ &lt;uses-permission android:name=&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot; /&gt;
+ ...
+&lt;/manifest>
+</pre>
+
+<div class="caution"><p><strong>Внимание!</strong>
+В настоящее время все приложения могут считывать данные из внешних
+хранилищ без специального разрешения. Однако в новой версии эта ситуация будет изменена. Если вашему приложению потребуется
+считать данные из внешнего хранилища (но не записать туда данные), вам необходимо будет декларировать разрешение {@link
+android.Manifest.permission#READ_EXTERNAL_STORAGE}. Чтобы обеспечить дальнейшую работу вашего приложения
+ожидаемым образом, вы должны сразу декларировать это разрешение до того, как изменения вступят в силу.</p>
+<pre>
+&lt;manifest ...>
+ &lt;uses-permission android:name=&quot;android.permission.READ_EXTERNAL_STORAGE&quot; /&gt;
+ ...
+&lt;/manifest>
+</pre>
+<p>Однако если ваше приложение использует разрешение {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE},
+оно косвенно получает разрешение на чтение данных из внешнего хранилища.</p>
+</div>
+
+<p>Для сохранения файлов во внутреннем хранилище
+не требуется никаких разрешений. У вашего приложения всегда будет разрешение на чтение и запись
+файлов в его каталог внутренней памяти.</p>
+
+
+
+
+
+<h2 id="WriteInternalStorage">Сохранение файла во внутренней памяти</h2>
+
+<p>При сохранении файла во внутреннюю память вы можете получить соответствующую директорию в виде
+{@link java.io.File}, вызвав один из двух методов:</p>
+
+<dl>
+ <dt>{@link android.content.Context#getFilesDir}</dt>
+ <dd>Возвращает {@link java.io.File}, соответствующий внутренней директории приложения.</dd>
+ <dt>{@link android.content.Context#getCacheDir}</dt>
+ <dd>Возвращает {@link java.io.File}, соответствующий внутренней директории файлов временной
+кэш-памяти приложения. Обязательно удаляйте каждый файл, когда он перестанет
+быть нужным, и устанавливайте разумное ограничение размера памяти, используемой в каждый момент времени,
+например, 1 МБ. Если системе будет не хватать места в хранилище, она может удалять файлы
+из кэш-памяти без уведомления.</dd>
+</dl>
+
+<p>Для создания файла в одной из этих директорий можно использовать конструктор {@link
+java.io.File#File(File,String) File()}, который передает элемент {@link java.io.File}, предоставляемый одним из вышеприведенных
+методов, с помощью которого указывается директория во внутренней памяти. Например:</p>
+
+<pre>
+File file = new File(context.getFilesDir(), filename);
+</pre>
+
+<p>Кроме того, можно вызвать метод {@link
+android.content.Context#openFileOutput openFileOutput()} для получения объекта {@link java.io.FileOutputStream}
+, производящего запись в файл во внутренней памяти. Вот пример
+записи текста в файл:</p>
+
+<pre>
+String filename = "myfile";
+String string = "Hello world!";
+FileOutputStream outputStream;
+
+try {
+ outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
+ outputStream.write(string.getBytes());
+ outputStream.close();
+} catch (Exception e) {
+ e.printStackTrace();
+}
+</pre>
+
+<p>Если вам потребуется кэшировать какие-то файлы, используйте {@link
+java.io.File#createTempFile createTempFile()}. Например, следующий метод извлекает
+имя файла из {@link java.net.URL} и создает файл с этим именем
+в каталоге внутренней кэш-памяти вашего приложения:</p>
+
+<pre>
+public File getTempFile(Context context, String url) {
+ File file;
+ try {
+ String fileName = Uri.parse(url).getLastPathSegment();
+ file = File.createTempFile(fileName, null, context.getCacheDir());
+ catch (IOException e) {
+ // Error while creating file
+ }
+ return file;
+}
+</pre>
+
+<p class="note"><strong>Примечание.</strong>
+Каталог вашего приложения во внутренней памяти указывается
+с использованием имени пакета приложения в определенном месте файловой системы Android.
+Технически другое приложение может прочитать ваши файлы во внутренней памяти, если вы установите для файлов
+режим Readable (доступно для чтения). Однако для этого другому приложению должны быть известны имя пакета вашего
+приложения и имена файлов. Другие приложения не могут просматривать внутренние каталоги вашего приложения и не имеют разрешений на
+чтение или запись, если вы специально не установите для своих файлов режим Readable (доступно для чтения) или Writable (доступно для записи). Следовательно, пока
+вы будете использовать режим {@link android.content.Context#MODE_PRIVATE} для своих файлов во внутренней памяти,
+они будут недоступны другим приложениям.</p>
+
+
+
+
+
+<h2 id="WriteExternalStorage">Сохранение файла во внешнем хранилище</h2>
+
+<p>Поскольку внешнее хранилище может быть недоступно&mdash; например, если пользователь установил
+хранилище в гнездо на компьютере или извлек из устройства SD-карту, &mdash; перед доступом к тому всегда следует
+проверять его доступность. Состояние внешнего
+хранилища можно узнать, если вызвать {@link android.os.Environment#getExternalStorageState}. Если возвращаемое состояние
+равнозначно {@link android.os.Environment#MEDIA_MOUNTED}, вы сможете выполнять с файлами операции чтения и
+записи. Например, следующие методы будут полезными для определения доступности
+хранилища данных:</p>
+
+<pre>
+/* Checks if external storage is available for read and write */
+public boolean isExternalStorageWritable() {
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+ return false;
+}
+
+/* Checks if external storage is available to at least read */
+public boolean isExternalStorageReadable() {
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
+ }
+ return false;
+}
+</pre>
+
+<p>Хотя внешнее хранилище может быть изменено пользователем и другими приложениями, существует две
+категории файлов, которые в нем можно сохранять:</p>
+
+<dl>
+ <dt>Общедоступные файлы</dt>
+ <dd>Файлы, которые
+должны быть доступны другим приложениям и пользователю. Когда пользователь удаляет ваше приложение,
+эти файлы должны оставаться доступны пользователю.
+ <p>Например, в эту категорию входят снимки, сделанные с помощью вашего приложения, а также другие загружаемые файлы.</p>
+ </dd>
+ <dt>Личные файлы</dt>
+ <dd>Это файлы, принадлежащие вашему приложению. Они должны удаляться при удалении
+вашего приложения пользователем. Хотя технически эти файлы доступны для пользователя и других приложений, поскольку находятся
+во внешнем хранилище, они не имеют никакой ценности для пользователей
+вне вашего приложения. Когда пользователь удаляет ваше приложение, система удаляет
+все файлы из каталога закрытых файлов вашего приложения во внешнем хранилище.
+ <p>Например, к этой категории относятся дополнительные ресурсы, загруженные приложением, и временные мультимедийные файлы.</p>
+ </dd>
+</dl>
+
+<p>Если вы хотите сохранить публичные файлы во внешнем хранилище, используйте методы
+{@link android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()} для получения {@link java.io.File}, отражающего
+соответствующий каталог во внешнем хранилище. Этот метод принимает аргумент, указывающий
+тип сохраняемого файла и позволяющий включить его в логическую структуру
+с другими публичными файлами, например, {@link android.os.Environment#DIRECTORY_MUSIC} или {@link
+android.os.Environment#DIRECTORY_PICTURES}. Например:</p>
+
+<pre>
+public File getAlbumStorageDir(String albumName) {
+ // Get the directory for the user's public pictures directory.
+ File file = new File(Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES), albumName);
+ if (!file.mkdirs()) {
+ Log.e(LOG_TAG, "Directory not created");
+ }
+ return file;
+}
+</pre>
+
+
+<p>Если вы хотите сохранить личные файлы вашего приложения, вы можете получить
+соответствующий каталог посредством, вызвав метод {@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()} и предоставив ему имя с указанием
+желаемого типа каталога. Каждый каталог, создаваемый таким способом, добавляется в родительский
+каталог, в котором объединены все файлы вашего приложения во внешнем хранилище. При удалении вашего приложения
+пользователем система удаляет этот каталог.</p>
+
+<p>Например, следующий метод позволит вам создать каталог для персонального фотоальбома:</p>
+
+<pre>
+public File getAlbumStorageDir(Context context, String albumName) {
+ // Get the directory for the app's private pictures directory.
+ File file = new File(context.getExternalFilesDir(
+ Environment.DIRECTORY_PICTURES), albumName);
+ if (!file.mkdirs()) {
+ Log.e(LOG_TAG, "Directory not created");
+ }
+ return file;
+}
+</pre>
+
+<p>Если ни одно из готовых имен подкаталогов не подходит для ваших файлов, вы можете вызвать {@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()} и передать аргумент {@code null}. При этом
+будет возвращен корневой каталог закрытого каталога вашего приложения во внешнем хранилище.</p>
+
+<p>Следует помнить, что {@link android.content.Context#getExternalFilesDir getExternalFilesDir()}
+создает каталог внутри каталога, который удаляется при удалении вашего приложения пользователем.
+Если сохраняемые вами файлы должны оставаться доступными после удаления вашего
+приложения пользователем &mdash; например, если ваше приложение работает с камерой, а пользователь хочет сохранить снимки, &mdash; вам
+следует использовать {@link android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()}.</p>
+
+
+<p>Вне зависимости от того, используете ли вы {@link
+android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()} для общих файлов или
+ link android.content.Context#getExternalFilesDir
+getExternalFilesDir()} для собственных файлов приложения, вы должны использовать имена каталогов, предоставляемые
+постоянными значениями API-интерфейсов, например,
+{@link android.os.Environment#DIRECTORY_PICTURES}. Эти имена каталогов обеспечивают
+правильную обработку файлов системой. Например, сохраненные в {@link
+android.os.Environment#DIRECTORY_RINGTONES} файлы относятся медиа-сканером системы в категорию рингтонов,
+а не музыки.</p>
+
+
+
+
+<h2 id="GetFreeSpace">Запрос доступного пространства</h2>
+
+<p>Если вам заранее известен объем сохраняемых данных, вы можете
+определить наличие достаточного пространства без исключения {@link
+java.io.IOException}, вызвав метод {@link java.io.File#getFreeSpace} или {@link
+java.io.File#getTotalSpace}. Эти методы позволяют узнать текущее доступное пространство и
+общее пространство в хранилище. Эта информация также позволять
+избежать переполнения объема хранилища сверх определенного уровня.</p>
+
+<p>Однако система не гарантирует возможность записи такого же количества байт, как указано
+в {@link java.io.File#getFreeSpace}. Если выводимое число на
+несколько мегабайт превышает размер данных, которые вы хотите сохранить, или если файловая система заполнена
+менее, чем на 90%, дальше можно действовать спокойно.
+В противном случае запись в хранилище осуществлять нежелательно.</p>
+
+<p class="note"><strong>Примечание.</strong> Вам необязательно проверять объем доступного места
+перед сохранением файла. Вы можете попробовать сразу записать файл, а затем
+определить событие {@link java.io.IOException}, если оно возникнет. Это может потребоваться,
+если вы точно не знаете, сколько нужно свободного места. Например, если вы
+меняете кодировку файла перед сохранением при конвертации изображения PNG в формат
+JPEG, вы не будете знать размер файла заранее.</p>
+
+
+
+
+<h2 id="DeleteFile">Удаление файла</h2>
+
+<p>Ненужные файлы всегда следует удалять. Наиболее простой способ удалить
+файл – вызвать в открытом файле ссылку {@link java.io.File#delete} на сам этот файл.</p>
+
+<pre>
+myFile.delete();
+</pre>
+
+<p>Если файл сохранен во внутреннем хранилище, вы также можете запросить {@link android.content.Context}, чтобы найти и
+удалить файл посредством вызова {@link android.content.Context#deleteFile deleteFile()}:</p>
+
+<pre>
+myContext.deleteFile(fileName);
+</pre>
+
+<div class="note">
+<p><strong>Примечание.</strong> При удалении пользователем вашего приложения система Android удаляет
+следующие элементы:</p>
+<ul>
+<li>Все файлы, сохраненные во внутреннем хранилище</li>
+<li>Все файлы, сохраненные во внешнем хранилище с использованием {@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()}.</li>
+</ul>
+<p>Однако вам следует регулярно вручную очищать кэш-память, чтобы удалить файлы, созданные с помощью
+{@link android.content.Context#getCacheDir()}, а также удалять любые
+другие ненужные файлы.</p>
+</div>
+
diff --git a/docs/html-intl/intl/ru/training/basics/data-storage/index.jd b/docs/html-intl/intl/ru/training/basics/data-storage/index.jd
new file mode 100644
index 0000000..064239b
--- /dev/null
+++ b/docs/html-intl/intl/ru/training/basics/data-storage/index.jd
@@ -0,0 +1,57 @@
+page.title=Сохранение данных
+page.tags=хранение данных,файлы,sql,база данных,настройки
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Необходимые знания и компоненты</h2>
+<ul>
+ <li>Android 1.6 (уровень API 4) или более поздняя версия</li>
+ <li>Знакомство с коллекциями значений ключей Map</li>
+ <li>Знакомство с файловым API-интерфейсом ввода/вывода Java</li>
+ <li>Знакомство с базами данных SQL</li>
+</ul>
+
+<h2>См. также:</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html">Варианты хранения</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>Большинству приложений Android необходимо сохранять данные (даже если это требуется только для сохранения информации о состоянии приложения)
+во время использования {@link android.app.Activity#onPause onPause()}, чтобы текущий прогресс пользователя не был утрачен. Большинству
+приложений, за исключением самых простых, также требуется сохранять настройки пользователя, а некоторым приложениям также требуется управление большими
+объемами информации в файлах и базах данных. В этом учебном курсе вы познакомитесь
+с основными вариантами хранения данных в Android, включая следующие:</p>
+
+<ul>
+ <li>Сохранение пар "ключ-значение" для простых типов данных в общем
+файле настроек.</li>
+ <li>Сохранение произвольных файлов в файловой системе Android</li>
+ <li>Использование баз данных под управлением SQLite</li>
+</ul>
+
+
+<h2>Уроки</h2>
+
+<dl>
+ <dt><b><a href="shared-preferences.html">Сохранение наборов "ключ-значение"</a></b></dt>
+ <dd>В этом уроке вы узнаете, как использовать общий файл настроек для хранения небольших объемов информации
+в парах "ключ-значение".</dd>
+
+ <dt><b><a href="files.html">Сохранение файлов</a></b></dt>
+ <dd>Узнайте, как сохранять простые файлы, например, для хранения длинных последовательностей данных, которые
+обычно читаются по порядку.</dd>
+
+ <dt><b><a href="databases.html">Сохранение данных в базах данных SQL</a></b></dt>
+ <dd>Этот урок содержит информацию об использовании баз данных SQLite для чтения и записи структурированных данных.</dd>
+
+</dl>
diff --git a/docs/html-intl/intl/ru/training/basics/data-storage/shared-preferences.jd b/docs/html-intl/intl/ru/training/basics/data-storage/shared-preferences.jd
new file mode 100644
index 0000000..61a0037
--- /dev/null
+++ b/docs/html-intl/intl/ru/training/basics/data-storage/shared-preferences.jd
@@ -0,0 +1,120 @@
+page.title=Сохранение наборов "ключ-значение"
+page.tags=хранение данных
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Содержание этого урока</h2>
+<ol>
+ <li><a href="#GetSharedPreferences">Получение средства обработки SharedPreferences</a></li>
+ <li><a href="#WriteSharedPreference">Запись в общие настройки</a></li>
+ <li><a href="#ReadSharedPreference">Чтение общих настроек</a></li>
+</ol>
+
+<h2>См. также:</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#pref">Использование общих настроек</a></li>
+</ul>
+
+</div>
+</div>
+
+
+<p>Если вы хотите сохранить относительно небольшой набор пар "ключ-значение",
+используйте {@link android.content.SharedPreferences} API-интерфейсы.
+Объект {@link android.content.SharedPreferences} указывает на файл,
+содержащий пары "ключ-значение", и предоставляет простые методы для чтения и записи. Управление каждым
+файлом {@link android.content.SharedPreferences} осуществляется
+с помощью инфраструктуры и может быть частным или общим.</p>
+
+<p>На этом уроке вы узнаете, как использовать API-интерфейсы {@link android.content.SharedPreferences} для сохранения и
+получения простых значений.</p>
+
+<p class="note"><strong>Примечание.</strong> API-интерфейсы {@link android.content.SharedPreferences} предназначены
+только для чтения и записи пар "ключ-значение", и их не следует путать с API-интерфейсами
+{@link android.preference.Preference}, которые помогают создать пользовательский интерфейс
+для настроек приложения (хотя они используют {@link android.content.SharedPreferences} в качестве своей
+реализации для сохранения настроек приложения). Информацию об использовании API-интерфейсов {@link
+android.preference.Preference} см. в руководстве <a href="{@docRoot}guide/topics/ui/settings.html">Настройки</a>.</p>
+
+<h2 id="GetSharedPreferences">Получение средства обработки SharedPreferences</h2>
+
+<p>Чтобы создать новый файл общих настроек или получить доступ к существующему,
+нужно вызвать один из двух методов:</p>
+<ul>
+ <li>{@link android.content.Context#getSharedPreferences(String,int)
+getSharedPreferences()} &mdash; Используйте этот метод, если вам потребуется несколько общих файлов настроек, идентифицируемых
+по имени, указанном в первом параметре. Этот метод можно вызвать из любого
+{@link android.content.Context} в вашем приложении.</li>
+ <li>{@link android.app.Activity#getPreferences(int) getPreferences()} &mdash; Используйте метод из
+{@link android.app.Activity}, если вам нужен
+только один файл общих настроек для операции. Поскольку при этом получается файл общих
+настроек по умолчанию, относящийся к операции, вам не нужно указывать имя.</li>
+</ul>
+
+<p>Например, следующий код выполняется в {@link android.app.Fragment}.
+Он получает доступ к файлу общих настроек,
+идентифицируемому по строке ресурсов {@code R.string.preference_file_key} и открывает его, используя
+закрытый режим так, что данный файл доступен только вашему приложению.</p>
+
+<pre>
+Context context = getActivity();
+SharedPreferences sharedPref = context.getSharedPreferences(
+ getString(R.string.preference_file_key), Context.MODE_PRIVATE);
+</pre>
+
+<p>Файлу общих настроек следует присваивать имя, которое ваше приложение может уникально
+идентифицировать, например {@code "com.example.myapp.PREFERENCE_FILE_KEY"}.</p>
+
+<p>Если для вашей операции нужен только один файл общих настроек, вы можете использовать метод
+{@link android.app.Activity#getPreferences(int) getPreferences()}:</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+</pre>
+
+<p class="caution"><strong>Внимание!</strong> Если вы создадите общий файл настроек
+с {@link android.content.Context#MODE_WORLD_READABLE} или {@link
+android.content.Context#MODE_WORLD_WRITEABLE}, ваши данные будут доступны всем другим приложениям, которым известен идентификатор
+файла.</p>
+
+
+<h2 id="WriteSharedPreference">Записать в общие настройки</h2>
+
+<p>Для записи в файл общих настроек создайте объект {@link
+android.content.SharedPreferences.Editor} посредством вызова {@link
+android.content.SharedPreferences#edit} в {@link android.content.SharedPreferences}.</p>
+
+<p>Передайте ключи и значения, которые хотите записать, с помощью таких методов, как {@link
+android.content.SharedPreferences.Editor#putInt putInt()} и {@link
+android.content.SharedPreferences.Editor#putString putString()}. Затем вызовите {@link
+android.content.SharedPreferences.Editor#commit} для сохранения изменений. Например:</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+SharedPreferences.Editor editor = sharedPref.edit();
+editor.putInt(getString(R.string.saved_high_score), newHighScore);
+editor.commit();
+</pre>
+
+
+<h2 id="ReadSharedPreference">Чтение общих настроек</h2>
+
+<p>Для получения значений из файла общих настроек следует вызвать такие, методы как {@link
+android.content.SharedPreferences#getInt getInt()} и {@link
+android.content.SharedPreferences#getString getString()}, предоставляя ключ для нужного
+вам значения, а также при желании значение по умолчанию, которое будет выводиться при отсутствии
+ключа. Например:</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+int defaultValue = getResources().getInteger(R.string.saved_high_score_default);
+long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue);
+</pre>
+
diff --git a/docs/html-intl/intl/ru/training/basics/intents/filters.jd b/docs/html-intl/intl/ru/training/basics/intents/filters.jd
new file mode 100644
index 0000000..0f5bb31
--- /dev/null
+++ b/docs/html-intl/intl/ru/training/basics/intents/filters.jd
@@ -0,0 +1,236 @@
+page.title=Разрешение другим приложениям на запуск вашей операции
+page.tags=намерения
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>Содержание этого урока</h2>
+<ol>
+ <li><a href="#AddIntentFilter">Добавление фильтра Intent</a></li>
+ <li><a href="#HandleIntent">Обработка объекта Intent в операции</a></li>
+ <li><a href="#ReturnResult">Возврат результата</a></li>
+</ol>
+
+<h2>См. также:</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">Общий доступ к простым данным</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">Общий доступ к файлам</a>
+</ul>
+ </div>
+</div>
+
+<p>Предыдущие два урока были посвящены одной теме – запуску операции вашего приложения
+в другом приложении. Однако если ваше приложение может выполнять операции, полезные другим приложениям,
+его нужно подготовить так, чтобы оно реагировало на запросы других приложений. Представьте, что вы разработали
+приложение для социальных сетей, позволяющее отправлять сообщения и фотографии друзьям пользователя. В этом случае в ваших интересах
+будет поддерживать объекты Intent (намерения) {@link android.content.Intent#ACTION_SEND}, чтобы пользователи могли
+поделиться контентом из другого приложения и запускать ваше приложение для выполнения требуемого действия.</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>.</p>
+
+<p>Если ваше приложение установлено на устройстве, система идентифицирует ваши
+фильтры Intent и добавляет информацию во внутренний каталог намерений, поддерживаемый всеми установленными приложениями.
+Когда приложение осуществляет вызов {@link android.app.Activity#startActivity
+startActivity()} или {@link android.app.Activity#startActivityForResult startActivityForResult()}
+с неявными объектами Intent, система определяет, какая операция (или какие операции) может отреагировать на объект
+Intent.</p>
+
+
+
+<h2 id="AddIntentFilter">Добавление фильтра Intent</h2>
+
+<p>Чтобы правильно определить, какие объекты Intent может обрабатывать ваша операция, каждый добавляемый вами фильтр Intent
+должен быть максимально определенным с точки зрения действий и данных, принимаемых
+операцией.</p>
+
+<p>Система может отправить указанный {@link android.content.Intent} в операцию, если у нее имеется
+фильтр Intent, соответствующий следующим критериям объекта {@link android.content.Intent}:</p>
+
+<dl>
+ <dt>Действие</dt>
+ <dd>Строка, называющая действие, которое необходимо выполнить. Обычно это одно из определяемых платформой значений,
+например, {@link android.content.Intent#ACTION_SEND} или {@link android.content.Intent#ACTION_VIEW}.
+ <p>Это следует указать в фильтре Intent с элементом <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code &lt;action&gt;}</a>.
+Указанное в этом элементе значение должно представлять собой полное имя строки действия, а не
+постоянное значение API-интерфейса (см. примеры ниже).</p></dd>
+
+ <dt>Данные</dt>
+ <dd>Описание данных, связанных с объектом Intent.
+ <p>Указывается в фильтре Intent с элементом <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data&gt;}</a>. Используя один
+или несколько атрибутов в этом элементе, вы можете указать только тип MIME, только префикс URI,
+только схему URI или из сочетание, а также другие индикаторы типа
+принимаемых данных.</p>
+ <p class="note"><strong>Примечание.</strong> Если вам не нужно декларировать специфику данных
+{@link android.net.Uri}(например, когда операция использует другие виды дополнительных данных вместо
+URI), вы должны указать только атрибут {@code android:mimeType} для декларирования типа
+данных, с которыми работает ваша операция, например, {@code text/plain} или {@code image/jpeg}.</p>
+</dd>
+ <dt>Категория</dt>
+ <dd>Дополнительный способ описания характеристик операции, обрабатывающей объект Intent который обычно связан
+с жестом пользователя или местом запуска. Система поддерживает несколько разных категорий,
+но большинство из них используется редко. Однако по умолчанию все неявные объекты Intent определяются с
+{@link android.content.Intent#CATEGORY_DEFAULT}.
+ <p>Это указывается в фильтре Intent с элементом <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code &lt;category&gt;}</a>
+.</p></dd>
+</dl>
+
+<p>В своем фильтре Intent вы можете декларировать критерии, принимаемые вашей операцией.
+Для этого нужно декларировать каждый из них с соответствующими элементами XML, вложенными в элемент <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter&gt;}</a>
+.</p>
+
+<p>Рассмотрим в качестве примера операцию с фильтром Intent, обрабатывающим объект {@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;data android:mimeType="image/*"/>
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p>Каждый входящий объект Intent указывает только одно действие и только один тип данных, однако допускается декларирование нескольких
+экземпляров элементов <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> и <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code
+&lt;data&gt;}</a> в каждом
+<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a>.</p>
+
+<p>Если поведение любых двух пар действий и данных является взаимоисключающим,
+необходимо создать отдельные фильтры Intent с указанием допустимых действий
+в сочетании с соответствующими типами данных.</p>
+
+<p>Допустим, ваша операция обрабатывает текст и изображения для объектов Intent {@link
+android.content.Intent#ACTION_SEND} и {@link
+android.content.Intent#ACTION_SENDTO}. В этом случае вам необходимо определить два отдельных фильтра Intent
+для двух действий, потому что объект Intent {@link
+android.content.Intent#ACTION_SENDTO} должен использовать данные {@link android.net.Uri} для указания
+адреса получателя с использованием схемы URI {@code send} или {@code sendto}. Например:</p>
+
+<pre>
+&lt;activity android:name="ShareActivity">
+ &lt;!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.SENDTO"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:scheme="sms" />
+ &lt;data android:scheme="smsto" />
+ &lt;/intent-filter>
+ &lt;!-- filter for sending text or images; accepts SEND action and text or image data -->
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.SEND"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:mimeType="image/*"/>
+ &lt;data android:mimeType="text/plain"/>
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p class="note"><strong>Примечание.</strong> Для получения неявных объектов Intent необходимо включить категорию
+{@link android.content.Intent#CATEGORY_DEFAULT} в фильтр Intent. Методы {@link
+android.app.Activity#startActivity startActivity()} и {@link
+android.app.Activity#startActivityForResult startActivityForResult()} обрабатывают все объекты Intent, как если бы они
+декларировали категорию {@link android.content.Intent#CATEGORY_DEFAULT}. Если вы не декларируете ее
+в своем фильтре Intent, никакие неявные объекты Intent не будут разрешаться в вашу операцию.</p>
+
+<p>Более подробную информацию об отправке и получении объектов {@link android.content.Intent#ACTION_SEND}
+Intent для социальных сетей и обмена данными см. в уроке <a href="{@docRoot}training/sharing/receive.html">Получение простых данных от других приложений</a>.</p>
+
+
+<h2 id="HandleIntent">Обработка объекта Intent в операции</h2>
+
+<p>Чтобы решить, какое действие выполнить в операции, можно прочитать объект {@link
+android.content.Intent}, использованный для ее запуска.</p>
+
+<p>При запуске операции нужно вызвать {@link android.app.Activity#getIntent()} для получения
+{@link android.content.Intent}, запустившего операцию. Это можно сделать в любое время в течение
+жизненного цикла операции, но обычно это делается при ранних обратных вызовах, например,
+{@link android.app.Activity#onCreate onCreate()} или {@link android.app.Activity#onStart()}.</p>
+
+<p>Например:</p>
+
+<pre>
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.main);
+
+ // Get the intent that started this activity
+ Intent intent = getIntent();
+ Uri data = intent.getData();
+
+ // Figure out what to do based on the intent type
+ if (intent.getType().indexOf("image/") != -1) {
+ // Handle intents with image data ...
+ } else if (intent.getType().equals("text/plain")) {
+ // Handle intents with text ...
+ }
+}
+</pre>
+
+
+<h2 id="ReturnResult">Возврат результата</h2>
+
+<p>Если вы хотите возвратить результат операции, которая вызвала вашу операцию, просто вызовите {@link
+android.app.Activity#setResult(int,Intent) setResult()}, чтобы указать код результата и объект {@link
+android.content.Intent} результата. Когда ваша операция завершается, и пользователь должен вернуться к первоначальной
+операции, вызовите {@link android.app.Activity#finish()}, чтобы закрыть (и уничтожить) вашу операцию. Например:
+</p>
+
+<pre>
+// Create intent to deliver some kind of result data
+Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");
+setResult(Activity.RESULT_OK, result);
+finish();
+</pre>
+
+<p>Вместе с результатом всегда нужно указывать код результата. Обычно этот код выглядит так: {@link
+android.app.Activity#RESULT_OK} или {@link android.app.Activity#RESULT_CANCELED}. После этого при
+необходимости можно указать дополнительные данные с помощью {@link android.content.Intent}.</p>
+
+<p class="note"><strong>Примечание.</strong> По умолчанию используется результат {@link
+android.app.Activity#RESULT_CANCELED}. Таким образом, если пользователь нажимает кнопку <em>Назад</em>
+до завершения действия и определения результата, первоначальная операция получает
+результат "Отменено".</p>
+
+<p>Если вам просто нужно возвратить целое число, указывающее один из нескольких вариантов результатов, вы можете установить
+для кода результата любое значение больше 0. Если вы используете код результата для передачи целого числа и вам
+не нужно включать {@link android.content.Intent}, можете вызвать метод {@link
+android.app.Activity#setResult(int) setResult()} и передать только код результата. Например:</p>
+
+<pre>
+setResult(RESULT_COLOR_RED);
+finish();
+</pre>
+
+<p>В этом случае может быть мало возможных результатов, и поэтому код результата представляет собой определяемое
+локально целое число (больше 0). Это хорошо работает, когда вы возвращаете результат операции
+в собственном приложении, поскольку получающая результат операция может ссылаться на общедоступное
+постоянное значение для определения значения кода результата.</p>
+
+<p class="note"><strong>Примечание.</strong> Не нужно проверять, запущена ли ваша операция,
+используя метод {@link
+android.app.Activity#startActivity startActivity()} или {@link
+android.app.Activity#startActivityForResult startActivityForResult()}. Просто вызовите метод {@link
+android.app.Activity#setResult(int,Intent) setResult()}, если запустивший вашу операцию объект Intent может
+ожидать результат. Если исходная операция вызвала метод {@link
+android.app.Activity#startActivityForResult startActivityForResult()}, система передаст
+ей результат, который вы передаете {@link android.app.Activity#setResult(int,Intent) setResult()}. В противном случае
+результат будет проигнорирован.</p>
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/ru/training/basics/intents/index.jd b/docs/html-intl/intl/ru/training/basics/intents/index.jd
new file mode 100644
index 0000000..cfb606d
--- /dev/null
+++ b/docs/html-intl/intl/ru/training/basics/intents/index.jd
@@ -0,0 +1,62 @@
+page.title=Взаимодействие с другими приложениями
+page.tags=объекты Intent,операция
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Необходимые знания и компоненты</h2>
+<ul>
+ <li>Базовые знания о жизненном цикле операции (см. раздел <a href="{@docRoot}training/basics/activity-lifecycle/index.html">Управление жизненным циклом
+операции</a>)</li>
+</ul>
+
+
+<h2>См. также:</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">Общий доступ к простым данным</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">Общий доступ к файлам</a>
+ <li><a href="http://android-developers.blogspot.com/2009/11/integrating-application-with-intents.html">
+Интеграция приложений с объектами Intent (сообщение в блоге)</a></li>
+ <li><a href="{@docRoot}guide/components/intents-filters.html">Объекты Intent и фильтры
+объектов Intent</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>В приложениях Android обычно имеется несколько <a href="{@docRoot}guide/components/activities.html">операций</a>. Каждая операция отображает
+пользовательский интерфейс, позволяющий пользователю выполнить определенную задачу (например, посмотреть карту или сделать снимок).
+Чтобы обеспечить переход пользователя от одной операции к другой, приложение должно использовать объект {@link
+android.content.Intent} для определения "намерения" приложения что-то сделать. При передаче системе
+{@link android.content.Intent} с помощью такого метода как {@link
+android.app.Activity#startActivity startActivity()} система использует {@link
+android.content.Intent} для идентификации и запуска соответствующего компонента приложения. Использование объектов Intent даже
+позволяет приложению запускать операции, содержащиеся в отдельном приложении.</p>
+
+<p>{@link android.content.Intent} может <em>явно</em> запускать определенный компонент
+(определенный экземпляр {@link android.app.Activity}) или <em>косвенно</em> запускать любой
+компонент, способный выполнить желаемую операцию (например, "сделать снимок").</p>
+
+<p>В этом учебном курсе рассказывается о том, как использовать {@link android.content.Intent} для простого
+взаимодействия с другими приложениями, например для запуска другого приложения, получения результата от этого приложения и обеспечения
+способности приложения реагировать на объекты Intent из других приложений.</p>
+
+<h2>Уроки</h2>
+
+<dl>
+ <dt><b><a href="sending.html">Направление пользователя в другое приложение</a></b></dt>
+ <dd>Вы узнаете, как создавать неявные объекты Intent для запуска других приложений, способных выполнить
+операцию.</dd>
+ <dt><b><a href="result.html">Получение результата операции</a></b></dt>
+ <dd>В этом уроке демонстрируется, как запустить другую операцию и получить ее результат.</dd>
+ <dt><b><a href="filters.html">Разрешение другим приложениям на запуск операции</a></b></dt>
+ <dd>В этом уроке демонстрируется, как разрешить другим приложениям использовать операции вашего приложения за счет определения
+фильтров объектов Intent, которые декларируют неявные намерения, принимаемые вашим приложением.</dd>
+</dl>
+
diff --git a/docs/html-intl/intl/ru/training/basics/intents/result.jd b/docs/html-intl/intl/ru/training/basics/intents/result.jd
new file mode 100644
index 0000000..8ab03d4
--- /dev/null
+++ b/docs/html-intl/intl/ru/training/basics/intents/result.jd
@@ -0,0 +1,178 @@
+page.title=Получение результата операции
+page.tags=объекты Intent
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>Содержание этого урока</h2>
+<ol>
+ <li><a href="#StartActivity">Запуск операции</a></li>
+ <li><a href="#ReceiveResult">Получение результата</a></li>
+</ol>
+
+<h2>См. также:</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">Общий доступ к простым данным</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">Общий доступ к файлам</a>
+</ul>
+
+ </div>
+</div>
+
+<p>Запуск другой операции не обязательно должен быть односторонним действием. Вы можете запустить другую операцию и
+получить от нее результат. Для получения результата нужно вызвать метод {@link android.app.Activity#startActivityForResult
+startActivityForResult()} (вместо {@link android.app.Activity#startActivity
+startActivity()}).</p>
+
+<p>Например, ваше приложение может запустить приложение для камеры и получить в качестве результата фотографию. Также вы
+можете запустить приложение "Люди", чтобы пользователь выбрал в нем
+контакт, и получить контактные данные в качестве результата.</p>
+
+<p>Разумеется, отвечающая операция должна быть способной возвратить результат. При возврате
+результат отправляется как другой объект {@link android.content.Intent}. Ваша операция получает
+его в обратном вызове {@link android.app.Activity#onActivityResult onActivityResult()}.</p>
+
+<p class="note"><strong>Примечание.</strong> Вы можете использовать явные и неявные результаты при вызове
+{@link android.app.Activity#startActivityForResult startActivityForResult()}. При запуске собственной
+операции для получения результата вы должны использовать явные результаты, чтобы получить
+именно ожидаемый результат.</p>
+
+
+<h2 id="StartActivity">Запуск операции</h2>
+
+<p>В объекте {@link android.content.Intent}, используемом для запуска операции
+для получения результата, нет ничего особенного, однако нужно передать дополнительный целочисленный аргумент методы {@link
+android.app.Activity#startActivityForResult startActivityForResult()}.</p>
+
+<p>Этот целочисленный аргумент представляет собой "код запроса", определяющий ваш запрос. Когда вы получите
+результат {@link android.content.Intent}, обратный вызов использует тот же самый код результата,
+чтобы ваше приложение могло правильно определить результат и понять, как его нужно обработать.</p>
+
+<p>Например, вот так можно запустить операцию, позволяющую пользователю выбрать контакт:</p>
+
+<pre>
+static final int PICK_CONTACT_REQUEST = 1; // The request code
+...
+private void pickContact() {
+ Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
+ pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
+ startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
+}
+</pre>
+
+
+<h2 id="ReceiveResult">Получение результата</h2>
+
+<p>Когда пользователь завершит последующую операцию и вернется, система вызовет метод вашей операции
+{@link android.app.Activity#onActivityResult onActivityResult()}. Этот метод содержит три
+аргумента:</p>
+
+<ul>
+ <li>Код запроса, переданный вами {@link
+android.app.Activity#startActivityForResult startActivityForResult()}.</li>
+ <li>Полученный в качестве результата код, указанный второй операцией. Или {@link
+android.app.Activity#RESULT_OK}, если операция была успешной, или {@link
+android.app.Activity#RESULT_CANCELED}, если пользователь отказался или операцию не удалось выполнить по какой-либо
+причине.</li>
+ <li>{@link android.content.Intent}, переносящий полученные данные.</li>
+</ul>
+
+<p>Например, результаты для намерения "Выбрать контакт" могут обрабатываться следующим образом:</p>
+
+<pre>
+&#64;Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // Check which request we're responding to
+ if (requestCode == PICK_CONTACT_REQUEST) {
+ // Make sure the request was successful
+ if (resultCode == RESULT_OK) {
+ // The user picked a contact.
+ // The Intent's data Uri identifies which contact was selected.
+
+ // Do something with the contact here (bigger example below)
+ }
+ }
+}
+</pre>
+
+<p>В этом примере результаты, {@link android.content.Intent} возвращаемые приложениями
+Android Контакты или Люди, предоставляют контент {@link android.net.Uri}, который идентифицирует
+выбранный пользователем контакт.</p>
+
+<p>Для успешной обработки результатов необходимо понимать, каким будет формат этих результатов
+{@link android.content.Intent}. Это просто, если результат возвращается одной из ваших
+собственных операций. Приложения, входящие в состав платформы Android, имеют собственные прикладные интерфейсы, так что
+вы можете рассчитывать на получение определенных результатов. Например, приложение "Люди" (приложение "Контакты" в старых
+версиях) всегда возвращает результат с URI контента, идентифицирующий выбранный контакт, а приложение
+"Камера" возвращает {@link android.graphics.Bitmap} в дополнительном {@code "data"} (см. урок
+<a href="{@docRoot}training/camera/index.html">Съемка фотографий</a>).</p>
+
+
+<h4>Бонус: Чтение контактных данных</h4>
+
+<p>Приведенный выше код, показывающий как получить результаты из приложения "Люди", не описывает
+детально чтение данных результатов, потому что для этого нужно более
+подробно рассказать о <a href="{@docRoot}guide/topics/providers/content-providers.html">поставщиках
+контента</a>. Если вам все-таки интересно, вот еще код, показывающий как запрашивать
+данные результатов для получения номера телефона выбранного контакта:</p>
+
+<pre>
+&#64;Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // Check which request it is that we're responding to
+ if (requestCode == PICK_CONTACT_REQUEST) {
+ // Make sure the request was successful
+ if (resultCode == RESULT_OK) {
+ // Get the URI that points to the selected contact
+ Uri contactUri = data.getData();
+ // We only need the NUMBER column, because there will be only one row in the result
+ String[] projection = {Phone.NUMBER};
+
+ // Perform the query on the contact to get the NUMBER column
+ // We don't need a selection or sort order (there's only one result for the given URI)
+ // CAUTION: The query() method should be called from a separate thread to avoid blocking
+ // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
+ // Consider using {@link android.content.CursorLoader} to perform the query.
+ Cursor cursor = getContentResolver()
+ .query(contactUri, projection, null, null, null);
+ cursor.moveToFirst();
+
+ // Retrieve the phone number from the NUMBER column
+ int column = cursor.getColumnIndex(Phone.NUMBER);
+ String number = cursor.getString(column);
+
+ // Do something with the phone number...
+ }
+ }
+}
+</pre>
+
+<p class="note"><strong>Примечание.</strong> До выхода версии Android 2.3 (API-интерфейс уровня 9) для выполнения
+запроса {@link android.provider.ContactsContract.Contacts Contacts Provider} (как
+показанный выше) ваше приложение должно было декларировать разрешение {@link
+android.Manifest.permission#READ_CONTACTS} (см. <a href="{@docRoot}guide/topics/security/security.html">Безопасность и разрешения</a>). Однако,
+начиная с версии Android 2.3, приложение "Контакты/Люди" дает вашему приложению временное
+разрешение на чтение данных Поставщика контактов при выводе результата. Это временное разрешение
+действует только в отношении конкретного запрошенного контакта, так что нельзя запрашивать другой контакт,
+кроме указанного объектом Intent {@link android.net.Uri}, если вы не хотите декларировать разрешение {@link
+android.Manifest.permission#READ_CONTACTS}.</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/ru/training/basics/intents/sending.jd b/docs/html-intl/intl/ru/training/basics/intents/sending.jd
new file mode 100644
index 0000000..da147ee
--- /dev/null
+++ b/docs/html-intl/intl/ru/training/basics/intents/sending.jd
@@ -0,0 +1,256 @@
+page.title=Направление пользователя в другое приложение
+page.tags=объекты Intent
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>Содержание этого урока</h2>
+<ol>
+ <li><a href="#Build">Создание явного объекта Intent</a></li>
+ <li><a href="#Verify">Проверка наличия приложения для получения объекта Intent</a></li>
+ <li><a href="#StartActivity">Запуск операции с объектом Intent</a></li>
+ <li><a href="#AppChooser">Отображение блока выбора приложения</a></li>
+</ol>
+
+<h2>См. также:</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">Общий доступ к простым данным</a></li>
+</ul>
+
+ </div>
+</div>
+
+<p>Одна из наиболее важных возможностей системы Android – способность приложений направлять пользователя в другое приложение
+в зависимости от желаемого действия. Например, если
+ваше приложение содержит адрес компании, который нужно показать на карте, вам не нужно встраивать в приложение операцию
+вывода карты. Вместо этого можно создать запрос на просмотр адреса
+с помощью {@link android.content.Intent}. В этом случае система Android запускает приложение,
+которое показывает адрес на карте.</p>
+
+<p>Как объяснялось в первом уроке <a href="{@docRoot}training/basics/firstapp/index.html">Создание
+первого приложения</a>, объекты Intent нужно использовать для навигации между операциями в собственном приложении. Обычно
+для этого используются <em>явные объекты Intent</em>, определяющие точное имя класса
+компонента, который вы хотите запустить. Однако если вы хотите, чтобы действие (например
+просмотр карты) выполнялось отдельным приложением, следует использовать <em>неявный объект Intent</em>.</p>
+
+<p>На этом уроке вы узнаете, как создать неявный объект Intent для определенного действия и использовать его
+для запуска операции, выполняющей действие в другом приложении.</p>
+
+
+
+<h2 id="Build">Создание неявного объекта Intent</h2>
+
+<p>Неявные объекты Intent не декларируют имя класса запускаемого компонента, а декларируют
+выполняемое действие. Действие указывает задачу, которую вы хотите выполнить, например <em>просмотр</em>,
+<em>правка</em>,<em> отправка</em> или <em>получение</em> чего-либо. Объекты Intent часто также содержат данные, ассоциируемые
+с действием, например адрес для просмотра или электронное сообщение для отправки.
+В зависимости от того, какой объект Intent вы хотите создать, данные могут относиться к типу {@link android.net.Uri},
+одному из нескольких других типов данных, либо объекту могут вообще не требоваться данные.</p>
+
+<p>Если ваши данные относятся к типу {@link android.net.Uri}, вы можете использовать простой конструктор {@link
+android.content.Intent#Intent(String,Uri) Intent()} для определения действия и
+данных.</p>
+
+<p>Приведем пример создания объекта Intent для запуска телефонного звонка, в котором данные {@link
+android.net.Uri} используются для указания телефонного номера:</p>
+
+<pre>
+Uri number = Uri.parse("tel:5551234");
+Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
+</pre>
+
+<p>Когда ваше приложение активирует этот объект Intent посредством вызова {@link android.app.Activity#startActivity
+startActivity()}, приложение "Телефон" инициирует звонок на указанный номер телефона.</p>
+
+<p>Вот еще несколько объектов Intent в сочетании с действиями и {@link android.net.Uri} парами
+данных:</p>
+
+<ul>
+ <li>Просмотр карты:
+<pre>
+// Map point based on address
+Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
+// Or map point based on latitude/longitude
+// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
+Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
+</pre>
+ </li>
+ <li>Просмотр веб-страницы:
+<pre>
+Uri webpage = Uri.parse("http://www.android.com");
+Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
+</pre>
+ </li>
+</ul>
+
+<p>Другие виды неявных объектов Intent требуют дополнительные данные, предоставляющие разные типы данных,
+например строки. Вы можете добавить один или несколько элементов дополнительных данных с помощью разных методов {@link
+android.content.Intent#putExtra(String,String) putExtra()}.</p>
+
+<p>Система по умолчанию определяет соответствующий тип MIME, который требует объект Intent на базе включенных данных
+{@link android.net.Uri}. Если не включать {@link android.net.Uri} в объект
+Intent, обычно нужно использовать {@link android.content.Intent#setType setType()} для указания типа
+данных, связанного с объектом Intent. Установка типа MIME также определяет, какие виды
+действий должен получать объект Intent.</p>
+
+<p>Вот некоторые объекты Intent, добавляющие дополнительные данные для указания желаемого действия:</p>
+
+<ul>
+ <li>Отправка электронного письма с вложением:
+<pre>
+Intent emailIntent = new Intent(Intent.ACTION_SEND);
+// The intent does not have a URI, so declare the "text/plain" MIME type
+emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
+emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients
+emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
+emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
+emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));
+// You can also attach multiple items by passing an ArrayList of Uris
+</pre>
+ </li>
+ <li>Создание события в календаре:
+<pre>
+Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
+Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);
+Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);
+calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
+calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
+calendarIntent.putExtra(Events.TITLE, "Ninja class");
+calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");
+</pre>
+<p class="note"><strong>Примечание.</strong> Этот объект Intent для создания события в календаре поддерживается только
+API-интерфейсами уровня 14 и выше.</p>
+ </li>
+</ul>
+
+<p class="note"><strong>Примечание.</strong> Очень важно определять объекты {@link
+android.content.Intent} как можно более конкретно. Например, если вы хотите вывести изображение
+с помощью объекта Intent {@link android.content.Intent#ACTION_VIEW}, вам следует указать тип MIME
+{@code image/*}. Это не даст объекту Intent запускать приложения для просмотра других типов
+данных (например картографические приложения).</p>
+
+
+
+<h2 id="Verify">Проверка наличия приложения для получения объекта Intent</h2>
+
+<p>Хотя платформа Android гарантирует выполнение объектов Intent во
+встроенных приложениях (таких как "Телефон", "Электронная почта" или "Календарь"), перед активацией объекта Intent всегда следует добавлять шаг
+проверки.</p>
+
+<p class="caution"><strong>Внимание!</strong> Если вы активируете объект Intent, а на устройстве не
+будет приложения, способного его обработать, ваше приложение закроется с ошибкой.</p>
+
+<p>Чтобы убедиться в наличии операции, реагирующей на объект Intent, вызовите метод {@link
+android.content.pm.PackageManager#queryIntentActivities queryIntentActivities()} для получения списка
+операций, способных обработать ваш {@link android.content.Intent}. Если полученный в результате список {@link
+java.util.List} не пустой, вы можете безопасно использовать данный объект Intent. Например:</p>
+
+<pre>
+PackageManager packageManager = {@link android.content.Context#getPackageManager()};
+List<ResolveInfo> activities = packageManager.queryIntentActivities(intent,
+ PackageManager.MATCH_DEFAULT_ONLY);
+boolean isIntentSafe = activities.size() > 0;
+</pre>
+
+<p>Если<code>isIntentSafe</code> имеет значение <code>true</code>, то хотя бы одно приложение отреагирует на объект
+Intent. Если же он имеет значение <code>false</code>, то на устройстве нет приложений для обработки данного объекта Intent.</p>
+
+<p class="note"><strong>Примечание.</strong> Такую проверку следует выполнять при первом
+запуске операции на случай, если понадобится отключить функцию, обрабатывающую объект Intent, до того, как пользователь попытается использовать
+ее. Если вам известно определенное приложение, которое может обработать данный объект Intent, вы можете указать ссылку,
+по которой пользователь может загрузить приложение (посмотрите, как <a href="{@docRoot}distribute/tools/promote/linking.html">добавить ссылку на свой продукт в Google
+Play</a>).</p>
+
+
+<h2 id="StartActivity">Запуск операции с объектом Intent</h2>
+
+<div class="figure" style="width:200px;margin-top:-10px">
+ <img src="{@docRoot}images/training/basics/intents-choice.png" alt="" />
+ <p class="img-caption"><strong>Рисунок 1.</strong> Пример диалогового окна выбора,
+которое отображается, если объект Intent могут обработать разные приложения.</p>
+</div>
+
+<p>После создания {@link android.content.Intent} и установки дополнительной информации вызовите {@link
+android.app.Activity#startActivity startActivity()} для отправки в систему. Если система
+идентифицирует несколько операций, способных обработать объект Intent, она выводит для пользователя диалоговое окно
+выбора приложения, как показано на рисунке 1. Если объект Intent может быть обработан
+только одной операцией, система сразу же запускает ее.</p>
+
+<pre>
+startActivity(intent);
+</pre>
+
+<p>Вот полный пример, показывающий, как создать объект Intent для просмотра карты, убедиться в наличии
+приложения для его обработки и запустить это приложение:</p>
+
+<pre>
+// Build the intent
+Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
+Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
+
+// Verify it resolves
+PackageManager packageManager = {@link android.content.Context#getPackageManager()};
+List&lt;ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
+boolean isIntentSafe = activities.size() > 0;
+
+// Start an activity if it's safe
+if (isIntentSafe) {
+ startActivity(mapIntent);
+}
+</pre>
+
+
+
+<h2 id="AppChooser">Отображение блока выбора приложения</h2>
+
+<div class="figure" style="width:200px;margin-top:-10px">
+ <img src="{@docRoot}images/training/basics/intent-chooser.png" alt="" />
+ <p class="img-caption"><strong>Рисунок 2</strong>. Диалог выбора.</p>
+</div>
+
+<p>Обратите внимание, что при запуске операции посредством передачи {@link android.content.Intent} в {@link
+android.app.Activity#startActivity startActivity()} и наличии нескольких приложений, реагирующих на
+объект Intent, пользователь может выбрать, какое из этих приложений использовать по умолчанию (для этого нужно установить флажок в нижней
+части диалогового окна; см. рисунок 1). Это удобно при выполнении действия, для которого
+пользователь обычно хочет всегда использовать одно и то же приложение, например при открытии веб-страницы (пользователи
+обычно используют один и тот же браузер) или создании снимка (пользователи обычно предпочитают одно и то же приложение камеры).</p>
+
+<p>Однако бывает так, что выполняемое действие может быть обработано несколькими приложениями, и пользователь
+каждый раз может использовать разные приложения &mdash; например, действие "Поделиться", для которого пользователи могут использовать разные
+приложения, &mdash; и в этом случае ваше приложение должно отображать диалоговое окно выбора приложения,
+как показано на рисунке 2. В диалоговом окне
+выбора приложения пользователь должен при каждом запуске выбирать, какое приложение использовать для действия (пользователь не
+может выбрать приложение по умолчанию).</p>
+
+<p>Чтобы отобразить блок выбора приложения, создайте {@link android.content.Intent} с помощью {@link
+android.content.Intent#createChooser createChooser()} и передайте его {@link
+android.app.Activity#startActivity startActivity()}. Например:</p>
+
+<pre>
+Intent intent = 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 chooser
+Intent chooser = Intent.createChooser(intent, title);
+
+// Verify the intent will resolve to at least one activity
+if (intent.resolveActivity(getPackageManager()) != null) {
+ startActivity(chooser);
+}
+</pre>
+
+<p>В результате отобразится диалоговое окно со списком приложений, которые могут отреагировать на объект Intent, переданный методу {@link
+android.content.Intent#createChooser createChooser()} и используют указанный текст в качестве
+заголовка диалога.</p>
+
+
+
diff --git a/docs/html-intl/intl/zh-cn/design/get-started/principles.jd b/docs/html-intl/intl/zh-cn/design/get-started/principles.jd
new file mode 100644
index 0000000..fbb46c9
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/design/get-started/principles.jd
@@ -0,0 +1,307 @@
+page.title=Android 设计原则
+@jd:body
+
+<p>以下设计原则由 Android用户体验团队秉承用户利益至上的理念而制定。他们还会继续为 Android 开发者和设计者针对不同类型的设备制定更详细的设计准则。
+
+
+
+</p>
+
+<p>
+在您应用自己的创意和设计思路时,请考虑这些原则,
+切勿固执己见。
+</p>
+
+<h2 id="enchant-me">让我着迷</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="delight-me">以意想不到的方式让我眼前一亮</h4>
+<p>漂亮的界面、精心布置的动画,或恰到好处的声效,都会带来快乐的体验。
+精细的效果能产生一种轻松的氛围,让人感觉自己拥有强大的力量。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_delight.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="real-objects-more-fun">实际对象要比按钮和菜单更有趣</h4>
+<p>让用户可以直接触摸和操作您应用中的对象,让执行任务更轻松,让用户更满意。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_real_objects.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="make-it-mine">我的应用我做主</h4>
+<p>用户喜欢添加个性化手势,因为这样会让他们觉得更顺手并且一切尽在他们的掌控之中。提供感性、美观的默认手势,但也要考虑到趣味性,不要让可选的定制手势妨碍主要任务的操作。
+
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_make_it_mine.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="get-to-know-me">让应用了解我</h4>
+<p>逐渐了解用户的偏好。不要让用户反复做出相同的选择,将之前的选择列作快捷选择。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_get_to_know_me.png">
+
+ </div>
+</div>
+
+<h2 id="simplify-my-life">让我的生活更轻松</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="keep-it-brief">语言简洁</h4>
+<p>使用简单的字词组成简短的句子。用户往往会跳过冗长的句子。</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_keep_it_brief.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="pictures-faster-than-words">图片比文字更直观</h4>
+<p>考虑以图示意。它们会吸引用户的注意力,并且比文字更高效。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_pictures.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="decide-for-me">为我决定,但最终由我做主</h4>
+<p>先提供您心目中的最佳选择,而不是先进行询问。太多的选择和决策会让人不悦。
+只是在您的选择可能不当时,才赋予用户“撤消”的权利。</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_decide_for_me.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="only-show-when-i-need-it">仅在我需要时显示我所需要的</h4>
+<p>如果一次性看到过多内容,用户会感到无所适从。将任务和信息细分为更小、更容易接受的片段。
+隐藏当前不必要的选项,并在用户操作期间提供指导。</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_information_when_need_it.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="always-know-where-i-am">我应该始终清楚自己在哪里</h4>
+<p>让用户感到轻车熟路。为应用中的不同场景赋予不同的外观,使用过渡效果来展现屏幕之间的关系。
+提供任务进度反馈。</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_navigation.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="never-lose-my-stuff">决不能让我的成果付诸东流</h4>
+<p>务必保存好用户耗费花时间创造的内容,让他们能随处访问这些内容。跨手机、平板电脑和计算机等平台,记住设置、个人手势和创作内容,
+让应用升级变得无比简单。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_never_lose_stuff.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="looks-same-should-act-same">如果看上去一样,其行为也应当相同</h4>
+<p>通过视觉上的显著差异(而不是微妙差异)帮助用户区分不同的功能。避免使用固定模式,那样会导致外观相似的场景中,用户执行同样的输入,应用却给出不同的响应。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_looks_same.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="interrupt-only-if-important">只在确实对我很重要时才打断我</h4>
+<p>就像优秀的个人助理一样,不要让上司被一些无关紧要的琐事打扰。用户希望专注于核心任务,除非确实非常重要并且情况紧急,否则,打断用户会让人烦不胜烦。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_important_interruption.png">
+
+ </div>
+</div>
+
+<h2 id="make-me-amazing">给我惊喜</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="give-me-tricks">到处为我提供有用的诀窍</h4>
+<p>如果能自己摸索出花样来,用户总是很开心的。利用直观的图案以及其他 Android 应用中常见的习惯手势,让您的应用更容易学习。
+例如,滑动手势就是一种不错的导航快捷手势。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_tricks.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="its-not-my-fault">不是我的错</h4>
+<p>在提醒用户改正错误时要礼貌。他们希望在使用您的应用时感觉自己很聪明。如果用户操作出错,请提供清晰的恢复说明,而不要让他们咀嚼详细的技术信息。如果您能在后台修复错误,那当然更好。
+
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_error.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="sprinkle-encouragement">多多鼓励</h4>
+<p>将复杂的任务分解为可轻松完成的小步骤。对操作提供反馈,哪怕只是微弱的灯光,也聊胜于无。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_sprinkle_encouragement.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="do-heavy-lifting-for-me">为我处理繁重事务</h4>
+<p>通过让新手完成他们认为自己不可能做到的事情,让他们感觉自己就像一名行家。例如,通过提供融合多种照片特效的快捷操作,只需几步,就可以让业余照片达到惊艳的效果。
+
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_heavy_lifting.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="make-important-things-fast">让重要事项能更快地完成</h4>
+<p>不是所有操作都同样重要。确定应用中哪些功能是最重要的,将这些功能放在便于找到和使用的地方,例如相机的快门按钮,或者音乐播放器中的暂停按钮。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_make_important_fast.png">
+
+ </div>
+</div>
diff --git a/docs/html-intl/intl/zh-cn/design/material/index.jd b/docs/html-intl/intl/zh-cn/design/material/index.jd
new file mode 100644
index 0000000..78e6d38
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/design/material/index.jd
@@ -0,0 +1,186 @@
+page.title=材料设计
+page.tags=Material, design
+page.type=设计
+page.image=design/material/images/MaterialLight.png
+
+@jd:body
+
+<!-- developer docs box -->
+<a class="notice-developers right" href="{@docRoot}training/material/index.html">
+ <div>
+ <h3>开发者文档</h3>
+ <p>使用材料设计创建应用</p>
+ </div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw">
+<div>
+ <h3>视频</h3>
+ <p>材料设计简介</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw">
+<div>
+ <h3>视频</h3>
+ <p>纸张和墨水:相关材料</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc">
+<div>
+ <h3>视频</h3>
+ <p>Google I/O 应用中的材料设计</p>
+</div>
+</a>
+
+
+
+<p itemprop="description">材料设计是专为设计适用于多个平台和设备的视觉、运动与互动效果而制定的综合指南。
+Android 现在已支持材料设计应用。
+如果要在您的 Android 应用中使用材料设计,请遵循<a href="http://www.google.com/design/spec">材料设计规范</a>内定义的指导方针,并使用 Android 5.0(API 级别 21)及以上版本所提供的新组件和功能。
+
+</p>
+
+<p>Android 为您提供了以下元素来构建材料设计应用:</p>
+
+<ul>
+ <li>全新的风格主题</li>
+ <li>用于设计复杂视图的全新小工具</li>
+ <li>用于自定义阴影和动画的全新 API</li>
+</ul>
+
+<p>有关在 Android 上实现材料设计的详细信息,请参阅<a href="{@docRoot}training/material/index.html">创建材料设计应用</a>。
+</p>
+
+
+<h3>材料主题</h3>
+
+<p>材料主题提供了新的应用样式和系统小工具,让您能够为触摸反馈以及活动转换设置配色工具以及默认动画。
+</p>
+
+<!-- two columns -->
+<div style="width:700px;margin-top:25px;margin-bottom:20px">
+<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>
+ </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>
+ </div>
+</div>
+<br style="clear:left"/>
+</div>
+
+<p>如需了解详细信息,请参阅<a href="{@docRoot}training/material/theme.html">使用材料主题
+</a>。</p>
+
+
+<h3>列表和卡片</h3>
+
+<p>Android 提供了两个全新的小工具,用于显示采用材料设计样式和动画的卡片和列表:
+</p>
+
+<!-- two columns -->
+<div style="width:700px;margin-top:25px;margin-bottom:20px">
+<div style="float:left;width:250px;margin-left:40px;margin-right:60px;">
+ <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" />
+ <p>全新的 <code>RecyclerView</code> 小工具是 <code>ListView</code>
+ 的可插入版本,支持不同的布局类型,并且具有更高性能。</p>
+</div>
+<div style="float:left;width:250px;margin-right:0px;">
+ <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" />
+ <p>全新的 <code>CardView</code> 小工具可让您展示卡片内的重要信息,并且有统一的观感。
+</p>
+</div>
+<br style="clear:left"/>
+</div>
+
+<p>如需了解详细信息,请参阅<a href="{@docRoot}training/material/lists-cards.html">创建列表和卡片</a>。
+</p>
+
+
+<h3>视图阴影</h3>
+
+<p>除了 X 和 Y 属性之外,Android 中的视图现在还提供了 Z
+属性。这一新属性用于展现视图的高度,从而确定:</p>
+
+<ul>
+<li>阴影的大小:Z 值越高的视图投射的阴影越长。</li>
+<li>绘制顺序:Z 值较高的视图会显示在其他视图的上方。</li>
+</ul>
+
+<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/videos/ContactsAnim.webm"/>
+ <source src="{@docRoot}design/videos/ContactsAnim.ogv"/>
+ </video>
+ </div>
+ <div style="font-size:10pt;margin-left:20px;margin-bottom:30px">
+ <em>如果要重新播放影片,请点击设备屏幕</em>
+ </div>
+</div>
+
+<p>如需了解详细信息,请参阅<a href="{@docRoot}training/material/shadows-clipping.html">定义阴影与裁剪视图</a>。
+</p>
+
+
+<h3>动画</h3>
+
+<p>动画 API 让您可为 UI 控件中的触摸反馈、视图状态更改以及活动转换创建自定义动画。
+</p>
+
+<p>这些 API 的作用是:</p>
+
+<ul>
+<li style="margin-bottom:15px">
+使用<strong>触摸反馈</strong>动画响应视图中的触摸事件。
+</li>
+<li style="margin-bottom:15px">
+使用<strong>循环显示</strong>动画隐藏和显示视图。
+</li>
+<li style="margin-bottom:15px">
+使用自定义<strong>活动转换</strong>动画切换活动。
+</li>
+<li style="margin-bottom:15px">
+使用<strong>曲线运动</strong>创建更自然的动画。
+</li>
+<li style="margin-bottom:15px">
+使用<strong>视图状态更改</strong>动画以动画形式呈现一个或多个视图属性的更改。
+</li>
+<li style="margin-bottom:15px">
+在视图状态更改期间以<strong>可绘制状态列表</strong>显示动画。
+</li>
+</ul>
+
+<p>触摸反馈动画内建于数个标准视图(例如按钮)中。全新的 API让您可以自定义这些动画并将其添加至自己的自定义视图中。
+</p>
+
+<p>如需了解详细信息,请参阅<a href="{@docRoot}training/material/animations.html">定义自定义动画</a>。
+</p>
+
+
+<h3>可绘制对象</h3>
+
+<p>下列可绘制对象的新功能将帮助您实现材料设计应用:</p>
+
+<ul>
+<li><strong>可绘制矢量</strong>可在不影响清晰度的情况下进行缩放,非常适合单色应用内图标。
+</li>
+<li><strong>可绘制底色</strong>可让您将位图定义为 alpha 蒙板,并在运行时为其着色。
+</li>
+<li><strong>颜色提取</strong>可让您从位图图像自动提取突出色彩。
+</li>
+</ul>
+
+<p>如需了解详细信息,请参阅<a href="{@docRoot}training/material/drawables.html">使用可绘制内容</a>。
+</p>
diff --git a/docs/html-intl/intl/zh-cn/design/patterns/confirming-acknowledging.jd b/docs/html-intl/intl/zh-cn/design/patterns/confirming-acknowledging.jd
new file mode 100644
index 0000000..aa4ae1f
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/design/patterns/confirming-acknowledging.jd
@@ -0,0 +1,70 @@
+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">
+ <img src="{@docRoot}design/media/confirm_ack_confirming.png">
+ <p><strong>确认</strong>是要求用户确认自己确实希望执行刚才所调用的操作。在某些情况下,确认随需要用户考虑的操作所相关的警告或关键信息一起显示。</p>
+ </div>
+ <div class="layout-content-col span-6">
+ <img src="{@docRoot}design/media/confirm_ack_acknowledge.png">
+ <p><strong>确知</strong>就是显示一段文字信息,让用户知道自己刚才调用的操作已经完成。这将消除系统正在执行的隐式操作的不确定性。在某些情况下,确知随撤消操作的选项一起显示。</p>
+ </div>
+</div>
+
+<p>以上述方式通知用户有助于减少用户对已发生或即将发生的事情的不确定性。确认或确知还可以有效防止用户犯下可能让自己后悔的错误。</p>
+
+<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">
+ <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">
+ <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">
+ <h4>示例:已保存中断的 Gmail 草稿</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_draftsave.png">
+ <p>在本例中,如果用户在 Gmail 撰写邮件屏幕中向后或向上导航,可能会发生一些意外情况,此时会自动保存当前草稿。Toast 形式的确知会明确告知这一点。它会在几秒钟后消失。</p>
+ <p>在这种情况下不能执行撤消操作,因为保存是由应用发起的,而不是由用户执行的。通过导航至草稿列表,可迅速方便地恢复邮件。</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+ <h4>示例:已删除 Gmail 会话</h4>
+ <img src="{@docRoot}design/media/confirm_ack_draft_deleted.png">
+ <p>在用户从 Gmail 中的列表删除某个会话后,会出现带撤消选项的确知。确知消息会一直等到用户采取无关操作才会消失,例如滚动列表。</p>
+ </div>
+</div>
+
+<h2>无需确认或确知</h2>
+<div class="layout-content-row">
+ <div class="layout-content-col span-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">
+ <h4>示例:从主屏幕删除应用</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_removeapp.png">
+ <p><strong>无需确认</strong>。这属于有意操作:用户必须将项目拖放到相对较大并且独立的目标上。因此,很难发生意外。但是如果用户反悔决定,只需数秒钟时间即可复原。</p>
+ <p><strong>无需确知</strong>。用户知道该应用会从主屏幕上消失,因为是他们将其拖走而使其消失的。</p>
+
+ </div>
+</div>
diff --git a/docs/html-intl/intl/zh-cn/design/patterns/navigation.jd b/docs/html-intl/intl/zh-cn/design/patterns/navigation.jd
new file mode 100644
index 0000000..339a2c5
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/design/patterns/navigation.jd
@@ -0,0 +1,213 @@
+page.title=使用返回和向上导航
+page.tags="navigation","activity","task","up navigation","back navigation"
+page.image=/design/media/navigation_between_siblings_gmail.png
+@jd:body
+
+<a class="notice-developers" href="{@docRoot}training/implementing-navigation/index.html">
+ <div>
+ <h3>开发者文档</h3>
+ <p>实现有效导航</p>
+ </div>
+</a>
+
+<p itemprop="description">一致的导航操作是整体用户体验的重要组成部分。如果基本的导航方法都不能保持一致,甚至让用户意想不到的话,恐怕没有比这更让人沮丧的事情了。
+Android 3.0对全局导航行为做出了重大改变。
+对用户来说,认真遵照“返回”和“向上”的指导准则可让应用的导航更可靠、更符合预期。
+</p>
+<p>Android 2.3 及更早的版本使用<em>返回</em>按钮来支持应用内的导航。在 Android 3.0 中引入操作栏后,出现了第二种导航机制:即<em>向上</em>按钮,由应用图标和左向箭头构成。
+
+</p>
+
+<img src="{@docRoot}design/media/navigation_with_back_and_up.png">
+
+<h2 id="up-vs-back">向上和返回</h2>
+
+<p>“向上”按钮用于根据屏幕之间的层级关系在应用中导航。
+例如,如果屏幕 A 显示项目列表,并且选择某个项目会调出屏幕 B(该屏幕显示项目的更多详情),则屏幕 B 应提供可返回屏幕 A 的“向上”按钮。
+
+</p>
+<p>如果屏幕是应用中层级最高的屏幕(即应用的主屏幕),则无需提供向上按钮。
+</p>
+
+<p>系统的“返回”按钮用于按照用户最近操作的屏幕历史记录,按时间逆序导航。
+它通常基于屏幕之间的时间关系,而非应用的层级关系。
+</p>
+
+<p>如果之前查看的屏幕也是当前屏幕的父级项,按下“返回”按钮的作用跟按下“向上”按钮一样 &mdash; 这种情况很常见。
+
+但是,“向上”按钮可确保用户留在应用内,与此不同的是,“返回”按钮可让用户返回到主屏幕,甚至返回不同的应用。
+</p>
+
+<img src="{@docRoot}design/media/navigation_up_vs_back_gmail.png">
+
+<p>“返回”按钮还支持与屏幕间导航并无直接关联的一些行为:
+</p>
+<ul>
+<li>清除浮动窗口(对话框、弹出窗口)</li>
+<li>清除上下文操作栏,并取消高亮显示所选项目</li>
+<li>隐藏屏幕键盘 (IME)</li>
+</ul>
+<h2 id="within-app">应用内导航</h2>
+
+<h4>通过多个入口点导航屏幕</h4>
+<p>有时,某个屏幕在应用层级中的位置并不固定,可以从多个入口点抵达 &mdash; 例如可从应用中的其他任何屏幕抵达设置屏幕。在这种情况下,选择“向上”按钮会返回到引用屏幕,其行为跟“返回”按钮相同。
+
+
+</p>
+<h4>更改屏幕中的视图</h4>
+<p>更改屏幕的视图选项不会更改“向上”或“返回”的行为:屏幕仍然位于应用层级中的同一位置,并且不会创建新的导航历史记录。
+</p>
+<p>此类视图更改的示例包括:</p>
+<ul>
+<li>使用选项卡和/或左右滑动切换视图</li>
+<li>使用下拉菜单(即折叠的选项卡)切换视图</li>
+<li>筛选列表</li>
+<li>列表排序</li>
+<li>更改显示特性(例如缩放)</li>
+</ul>
+<h4>在同级屏幕之间导航</h4>
+<p>如果您的应用支持从项目列表导航至其中某个项目的详情视图,通常最好支持从该项目导航到列表中该项目之前或之后的另一项目。
+
+例如,在 Gmail 中,只需在会话中向左或向右滑动,即可轻松查看同一收件箱中较新或较旧的会话。
+在某个屏幕内更改视图这样的导航不会改变“向上”或“返回”的行为。
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_gmail.png">
+
+<p>然而,当在多个彼此相关、但并未通过引用列表绑定在一起的详情视图之间浏览时,例如,在 Play 商店中同一开发商开发的多款应用或者同一艺术家推出的多张专辑之间切换浏览时,会发生值得注意的例外情况。
+
+在这些情况下,跟踪每个链接不会创建历史记录,这就导致点击“返回”按钮时会逐一显示之前查看过的每个屏幕。
+点击“向上”按钮则会直接绕过这些相关的屏幕并导航至最近查看的容器屏幕。
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_market1.png">
+
+<p>您可以根据详情视图的实际情况让“向上”按钮的行为更加智能。
+将上述 Play 商店示例进一步展开,设想用户从查看过的上一本图书导航至电影改编详情。
+在这种情况下,“向上”按钮可返回至用户之前导航时未经历过的容器(电影)。
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_market2.png">
+
+<h2 id="into-your-app">通过主屏幕小工具和通知进入您的应用</h2>
+
+<p>使用主屏幕小工具或通知,您可以帮助用户直接导航至应用中的深层屏幕。
+例如,Gmail 的收件箱小工具和新消息通知都可绕过收件箱屏幕,让用户直接进入会话视图。
+</p>
+
+<p>对于这两种情况,请按下述说明处理“向上”按钮:</p>
+
+<ul>
+<li><em>如果目的屏幕通常通过应用</em>中的某个特定屏幕抵达,“向上”按钮应导航至该屏幕。
+</li>
+<li><em>否则</em>,“向上”按钮应导航至应用的顶级屏幕(“主屏幕”)。</li>
+</ul>
+
+<p>对于“返回”按钮,您应将指向应用顶级屏幕的完整向上导航路径插入到任务的返回栈,从而让导航更具预见性。
+这样,如果用户忘记了之前是如何进入您的应用的,则可以在退出之前导航至应用的顶级屏幕。
+
+</p>
+
+<p>例如,Gmail 的主屏幕小工具有一个按钮可以让您直接进入写邮件屏幕。
+在写邮件屏幕上使用“向上”或“返回”可让用户进入“收件箱”,而在收件箱屏幕上使用“返回”则可回到主屏幕。
+</p>
+
+<img src="{@docRoot}design/media/navigation_from_outside_back.png">
+
+<h4>间接通知</h4>
+
+<p>如果您的应用需要同时提供关于多个事件的信息,可使用一条通知将用户引导至某个间隙屏幕。
+该屏幕将这些事件汇总,并为用户提供深度导航应用的路径。这种样式的通知称为<em>间接通知</em>。
+
+</p>
+
+<p>与标准(直接)通知不同,在间接通知的间隙屏幕上按下“返回”会让用户回到触发通知的点 &mdash; 不会在返回栈中插入额外的屏幕。
+
+一旦用户从应用的间隙屏幕进入应用的更深层级,则“向上”和“返回”按钮的行为就与用于标准通知时相同,如上所述:在应用内部导航,而非返回至间隙屏幕。
+
+</p>
+
+<p>例如,假设 Gmail 中的用户收到来自日历的间接通知。触摸该通知会打开间隙屏幕,该屏幕会显示数个不同事件的提醒。
+
+在间隙屏幕上触摸“返回”会让用户回到 Gmail。触摸特定事件会让用户离开间隙屏幕并进入完整的日历应用,以显示事件的详情。
+
+在事件详情屏幕上,使用“向上”和“返回”可导航至日历的顶级视图。</p>
+
+<img src="{@docRoot}design/media/navigation_indirect_notification.png">
+
+<h4>弹出通知</h4>
+
+<p><em>弹出通知</em>会绕过抽屉式通知栏,直接显示在用户面前。
+一般很少使用这种通知,<strong>仅在需要即时响应并且有必要中断用户当前操作时使用</strong>。
+例如,Talk 使用这种方式来提醒用户收到了好友加入视频聊天的邀请,因为该邀请将在几秒之后自动过期。
+
+</p>
+
+<p>从导航行为的角度来看,弹出通知会密切跟踪间接通知的间隙屏幕的行为。
+使用“返回”会清除弹出通知。如果用户从弹出通知导航至通知应用中,则“向上”和“返回”会依照标准通知的规则在应用内导航。
+
+</p>
+
+<img src="{@docRoot}design/media/navigation_popup_notification.png">
+
+<h2 id="between-apps">在应用之间导航</h2>
+
+<p>Android 系统的一个基本优势在于能够让应用相互激活,这样用户就可以直接从一个应用导航到另一个应用。
+例如,需要获取照片的应用可激活相机应用,后者可将照片返回给前者。这对于开发者和用户来说都极为有利,开发者可以方便地利用来自其他应用的代码,而用户则在执行常用操作时可以获得一致的体验。
+
+
+
+</p>
+
+<p>为了理解应用到应用的导航,必须理解下面探讨的 Android 框架行为
+。</p>
+
+<h4>活动、任务和意向</h4>
+
+<p>在 Android 中,<strong>活动</strong>是一个应用组件,用于定义信息屏幕以及用户可执行的所有相关操作。
+您的应用是活动的集合,由您创建的活动以及从其他应用重用的活动构成。
+</p>
+
+<p><strong>任务</strong>是用户为达成某个目标而执行的活动序列。一个
+任务可以只利用一个应用的活动,也可以利用来自多个不同应用的活动。
+</p>
+
+<p><strong>意向</strong>是应用的一种机制,用于发出信号以表明需要另一个应用的辅助才能执行某个操作。
+应用的活动可指示其可响应哪些意向。
+对于诸如“分享”这样的常用意向,用户可能安装有许多可执行该请求的应用。
+</p>
+
+<h4>示例:在应用之间导航以支持分享</h4>
+
+<p>要了解如何结合使用活动、任务和意向,可以考虑一个应用如何让用户通过使用另一应用来分享内容的例子。例如,从主屏幕启动 Play 商店应用可启动新任务 A(参见下图)。
+
+在 Play 商店中导航并触摸某本促销图书来查看其详情之后,用户会停留在该任务中并通过添加活动来扩展该任务。
+触发“分享”操作会通过一个对话框来提示用户选择活动,该对话框中会列出来自不同应用、之前已注册用于处理“分享”意向的每一种活动。
+
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_inward.png">
+
+<p>如果用户选择通过 Gmail 分享,则会以延续任务 A 的形式添加 Gmail 的写邮件活动 &mdash; 而不会创建新任务。
+如果 Gmail 在后台还运行有自己的任务,该任务不会受影响。
+</p>
+
+<p>在写邮件活动中,发送邮件或触摸“返回”按钮会让用户回到图书详情活动。
+之后继续触摸“返回”会在 Play 商店中继续回退,直至抵达主屏幕。
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_back.png">
+
+<p>尽管如此,用户可通过在写邮件活动中触摸“向上”按钮表明其希望留在 Gmail 中。
+此时会显示 Gmail 的会话列表活动,并为其创建新任务 B。新任务都始于主屏幕,因此从会话列表触摸“返回”按钮,始终会回到主屏幕。
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_up.png">
+
+<p>任务 A 保持在后台运行,用户可稍后回到该任务(例如通过“最近使用的应用”屏幕)。
+如果 Gmail 在后台还运行有自己的任务,该任务会被任务 B 取代 &mdash; 之前的上下文会被丢弃,以使用户达成新目标。
+</p>
+
+<p>如果您的应用经过注册,以使用应用中的深层活动来处理意向,可参阅<a href="#into-your-app">通过主屏幕小工具和通知进入您的应用</a>,获得有关如何指定“向上”导航行为的指导。
+
+</p>
diff --git a/docs/html-intl/intl/zh-cn/design/patterns/notifications.jd b/docs/html-intl/intl/zh-cn/design/patterns/notifications.jd
new file mode 100644
index 0000000..57e02e4
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/design/patterns/notifications.jd
@@ -0,0 +1,872 @@
+page.title=通知
+page.tags="notifications","design","L"
+@jd:body
+
+ <a class="notice-developers" href="{@docRoot}training/notify-user/index.html">
+ <div>
+ <h3>开发者文档</h3>
+ <p>通知用户</p>
+ </div>
+</a>
+
+<a class="notice-designers" href="notifications_k.html">
+ <div>
+ <h3>Android 4.4 及更低版本中的通知</h3>
+ </div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=Uiq2kZ2JHVY">
+<div>
+ <h3>视频</h3>
+ <p>DevBytes:Android L 开发者预览当中的通知</p>
+</div>
+</a>
+
+<style>
+ .col-5, .col-6, .col-7 {
+ margin-left:0px;
+ }
+</style>
+
+<p>通知系统可让用户随时了解应用中的相关和即时事件,例如来自好友的新聊天信息或日历事件。可将通知视作新闻频道,在重要的事件发生时提醒用户注意,或者当作日志,在用户未注意时记录事件&mdash;可在用户的所有 Android 设备上按需同步。
+
+
+
+
+
+</p>
+
+<h4 id="New"><strong>Android 5.0 新增内容</strong></h4>
+
+<p>在 Android 5.0 中,通知在结构、外观和功能方面获得了重要的更新:
+</p>
+
+<ul>
+ <li>通知在外观上发生了更改,与新的材料设计主题保持一致。
+</li>
+ <li> 通知现在可以在设备锁定屏幕上使用,而敏感信息仍然可以隐藏于背后。
+
+</li>
+ <li>设备在使用时收到的高优先级通知现在采用名为浮动通知的新格式。
+</li>
+ <li>云同步通知:在一台 Android 设备上清除通知,则在其他设备上也会将其清除。
+
+</li>
+</ul>
+
+<p class="note"><strong>注:</strong>该版本 Android 的通知设计与之前的版本大不相同。
+
+有关之前版本通知设计的信息,请参阅<a href="./notifications_k.html"> Android 4.4 及更低版本中的通知</a>。
+</p>
+
+<h2 id="Anatomy">通知详解</h2>
+
+<p>本部分介绍通知的基本组成部分,及其在不同类型设备上显示的方式。
+</p>
+
+<h3 id="BaseLayout">基本布局</h3>
+
+<p>所有通知至少要包括一个基本布局,包括:</p>
+
+<ul>
+ <li> 通知的<strong>图标</strong>。图标以符号形式表示来源应用。如果应用生成多个类型的通知,它也可用于指明通知类型。
+
+
+</li>
+ <li> 通知<strong>标题</strong>以及其他
+<strong>文本</strong>。</li>
+ <li> <strong>时间戳</strong>。</li>
+</ul>
+
+<p>利用 {@link android.app.Notification.Builder Notification.Builder}为之前版本平台创建的通知,其外观和行为方式与在 Android
+5.0 中完全相同,唯一的变动在于系统为您处理通知的方式存在细微的样式变动。
+
+如需了解之前 Android 版本通知设计的详细信息,请参阅<a href="./notifications_k.html"> Android 4.4 及更低版本中的通知</a>。
+
+</p></p>
+
+
+ <img style="margin:20px 0 0 0" src="{@docRoot}images/android-5.0/notifications/basic_combo.png" alt="" width="700px" />
+
+
+<div style="clear:both;margin-top:20px">
+ <p class="img-caption">
+ 手持设备通知(左)和穿戴设备(右)上同一通知的基本布局,带有用户照片和通知图标
+
+ </p>
+ </div>
+
+<h3 id="ExpandedLayouts">展开布局</h3>
+
+
+<p>您可以选择让应用的通知提供多少信息详情。
+它们可显示消息的前几行,也可以显示更大的预览图像。
+额外的信息可以为用户提供更多上下文,并且,在某些情况下,可能允许用户完整阅读消息。
+
+
+用户可进行两指缩放或执行单指滑移,在紧凑和展开布局之间切换。
+
+
+ 对于单一事件通知,Android 提供了三种展开布局模板(文本、收件箱和图像),供您在应用中使用。
+
+下图展示单一事件通知在手持设备(左)和穿戴式设备(右)上的外观。
+
+</p>
+
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/expandedtext_combo.png"
+ alt="" width="700px" height;="284px" />
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/stack_combo.png"
+ alt="" width="700px" height;="284px" />
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/ExpandedImage.png"
+ alt="" width="311px" height;="450px" />
+
+<h3 id="actions" style="clear:both; margin-top:40px">操作</h3>
+
+<p>Android 支持在通知底部显示可选的操作。通过操作,用户可在通知栏中处理最常见的任务,而无需打开来源应用。这样可加快交互的速度,而通过结合使用滑动清除通知的功能,有助于用户专注于对自身重要的通知。
+
+
+
+
+
+</p>
+
+
+ <img src="{@docRoot}images/android-5.0/notifications/action_combo.png" alt="" width="700px" />
+
+
+
+<p style="clear:both">请慎重考虑要在通知中包含多少操作。
+您加入的操作越多,用户就越无所适从。
+请通过只包含最重要且有意义的操作,尽量减少通知中的操作数量。
+
+
+</p>
+
+<p>适合在通知中使用的操作具有如下特点:</p>
+
+<ul>
+ <li> 对正在显示的内容类型必要、常用且常见
+
+ <li> 让用户可以迅速完成任务
+</ul>
+
+<p>避免以下类型的操作:</p>
+
+<ul>
+ <li> 含义模糊
+ <li> 跟通知的默认操作一样(例如“阅读”或“打开”)
+
+</ul>
+
+
+
+<p>您最多可以指定三个操作,每个操作由操作图标和名称组成。
+
+ 通过为简单的基本布局添加操作,可以展开该通知,即使该通知没有展开布局,此方法仍然有效。
+
+由于操作仅对展开的通知显示(否则会隐藏),因此要确保用户从通知调用的任何操作都可在相关联的应用中使用。
+
+
+
+
+</p>
+
+<h2 style="clear:left">浮动通知</h2>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/hun-example.png" alt="" width="311px" />
+ <p class="img-caption">
+ 出现在沉浸式应用顶部的浮动通知(手机来电,高优先级)示例
+
+
+ </p>
+</div>
+
+<p>收到高优先级通知时(见右侧),它会向用户短时间显示一个包含可选操作的展开布局。
+
+</p>
+<p> 之后,通知会缩回通知栏。
+如果通知的<a href="#correctly_set_and_manage_notification_priority">优先级</a>标志为高、最大或全屏,则会得到浮动通知。
+</p>
+
+<p><b>浮动通知的范例</b></p>
+
+<ul>
+ <li> 使用设备时来电</li>
+ <li> 使用设备时闹铃</li>
+ <li> 新的短信</li>
+ <li> 电池电量过低</li>
+</ul>
+
+<h2 style="clear:both" id="guidelines">指导原则</h2>
+
+
+<h3 id="MakeItPersonal">个人化</h3>
+
+<p>对于他人发送的项目通知(例如消息或状态更新),请使用
+{@link android.app.Notification.Builder#setLargeIcon setLargeIcon()} 包含此人的头像。
+另外将有关此人的信息附加到通知的元数据(参阅 {@link android.app.Notification#EXTRA_PEOPLE})。
+</p>
+
+<p>您通知的主图标仍然会显示,因此,该用户可将其与状态栏中显示的图标相关联。
+
+</p>
+
+
+<img src="{@docRoot}images/android-5.0/notifications/Triggered.png" alt="" width="311px" />
+<p style="margin-top:10px" class="img-caption">
+ 显示触发通知的用户以及该用户所发送信息的通知。
+</p>
+
+
+<h3 id="navigate_to_the_right_place">导航至正确位置</h3>
+
+<p>在用户触摸通知的正文时(在操作按钮的外面),打开应用并定位至正确的位置,以便用户可查看通知中引用的数据并据此操作。
+
+
+在大多数情况下,该位置是某个数据项目(例如消息)的详情视图,但如果是存档通知,那么也可能是摘要视图。
+
+如果您的应用将用户带到应用顶层以下的任何位置,可将导航插入应用的返回栈,这样用户就可以通过按下系统返回按钮返回至顶层。
+
+如需了解详细信息,请参阅<a href="{@docRoot}design/patterns/navigation.html#into-your-app">导航</a>设计模式中的“通过主屏幕小工具和通知进入您的应用”<em></em>。
+
+</p>
+
+<h3 id="correctly_set_and_manage_notification_priority">正确设置和管理通知优先级。
+
+</h3>
+
+<p>Android 支持通知的优先级标志。该标志可以影响您的通知相对于其他通知出现的位置,并且可以帮助确保用户始终能在第一时间看到对他们最重要的通知。
+
+
+在发布通知时,您可以选择下列优先级之一:
+
+</p>
+<table>
+ <tr>
+ <td class="tab0">
+<p><strong>优先级</strong></p>
+</td>
+ <td class="tab0">
+<p><strong>用法</strong></p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>MAX</code></p>
+</td>
+ <td class="tab1">
+<p>用于重要和紧急的通知,告知用户属于时间关键型状况,或者必须予以解决方可继续执行某个特定任务。
+
+
+</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>HIGH</code></p>
+</td>
+ <td class="tab1">
+<p>主要用于重要通信,例如包含用户特别感兴趣的内容的消息或聊天事件。高优先级通知会触发浮动通知显示。
+
+</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>DEFAULT</code></p>
+</td>
+ <td class="tab1">
+<p>用于不属于此处所述其他任何优先级的所有通知。</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>LOW</code></p>
+</td>
+ <td class="tab1">
+<p>用于您希望告知用户但不是很紧急的通知。
+低优先级通知最好显示在列表的底部,这里正适合放置公共事项或无收件人姓名的社交更新之类的通知:
+
+用户要求接收相关通知,但是这些通知的优先级永远不会高于紧急或直接通信。
+
+
+</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>MIN</code></p>
+</td>
+ <td class="tab1">
+<p>用于上下文或背景信息,例如天气信息或上下文位置信息。最低优先级通知不会出现在状态栏中。
+
+用户可在展开的通知栏上找到它们。
+</p>
+</td>
+ </tr>
+</table>
+
+
+<h4 id="how_to_choose_an_appropriate_priority"><strong>如何选择合适的优先级</strong>
+
+</h4>
+
+<p><code>DEFAULT</code>、<code>HIGH</code> 和 <code>MAX</code> 是中断优先级别,在活动过程中有中断用户的风险。
+
+为了避免打扰应用的用户,中断优先级仅保留用于以下通知
+:</p>
+
+<ul>
+ <li> 涉及另一个用户</li>
+ <li> 时间敏感</li>
+ <li> 可能会立即改变用户在现实世界中的行为</li>
+</ul>
+
+<p>设置为 <code>LOW</code> 和 <code>MIN</code> 的通知可能仍然对用户很重要:
+很多通知(如果不是绝大多数)不需要用户立即注意,也不需要振动,但仍然包含用户选择查看通知时将会觉得重要的信息。
+
+
+<code>LOW</code> 和 <code>MIN</code>优先级通知的条件包括:
+</p>
+
+<ul>
+ <li> 不涉及其他用户</li>
+ <li> 不属于时间敏感型</li>
+ <li> 包含用户可能感兴趣但可选择在空闲时浏览的内容
+</li>
+</ul>
+
+
+ <img src="{@docRoot}images/android-5.0/notifications/notifications_pattern_priority.png" alt="" width="700" />
+
+
+<h3 style="clear:both" id="set_a_notification_category">设置通知类别
+</h3>
+
+<p>如果通知属于以下预定义类别(参阅下文)之一,则为其分配相应的类别。
+
+诸如通知栏(或其他任何通知侦听器)这样的系统 UI 项目,可使用该信息来进行评级和筛选决策。
+
+</p>
+<table>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_CALL">CATEGORY_CALL</a></code></p>
+</td>
+ <td>
+<p>来电(语音或视频)或相似的同步通信请求
+</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_MESSAGE">CATEGORY_MESSAGE</a></code></p>
+</td>
+ <td>
+<p>传入的直接消息(短信、即时消息等)</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_EMAIL">CATEGORY_EMAIL</a></code></p>
+</td>
+ <td>
+<p>异步群发消息(电子邮件)</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_EVENT">CATEGORY_EVENT</a></code></p>
+</td>
+ <td>
+<p>日历事件</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_PROMO">CATEGORY_PROMO</a></code></p>
+</td>
+ <td>
+<p>促销或广告</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_ALARM">CATEGORY_ALARM</a></code></p>
+</td>
+ <td>
+<p>闹铃或定时器</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_PROGRESS">CATEGORY_PROGRESS</a></code></p>
+</td>
+ <td>
+<p>长时间运行的后台操作的进度</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SOCIAL">CATEGORY_SOCIAL</a></code></p>
+</td>
+ <td>
+<p>社交网络或共享更新</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_ERROR">CATEGORY_ERROR</a></code></p>
+</td>
+ <td>
+<p>后台操作或身份验证状态中的错误</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_TRANSPORT">CATEGORY_TRANSPORT</a></code></p>
+</td>
+ <td>
+<p>媒体传输播放控制</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SYSTEM">CATEGORY_SYSTEM</a></code></p>
+</td>
+ <td>
+<p>系统或设备状态更新。保留给系统使用。</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SERVICE">CATEGORY_SERVICE</a></code></p>
+</td>
+ <td>
+<p>正在运行的后台服务的指示</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_RECOMMENDATION">CATEGORY_RECOMMENDATION</a></code></p>
+</td>
+ <td>
+<p>对于某个事件的特定、及时建议。例如,新闻应用可能会建议用户接下来可能想要阅读的新话题。
+
+</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_STATUS">CATEGORY_STATUS</a></code></p>
+</td>
+ <td>
+<p>有关设备或上下文状态的持续信息</p>
+</td>
+ </tr>
+</table>
+
+<h3 id="summarize_your_notifications">通知摘要</h3>
+
+<p>如果特定类型的通知已经在您的应用尝试发送同类型的新通知时挂起,可将它们合并到单个应用摘要通知中,而不要新建对象。
+
+</p>
+
+<p>摘要通知会生成摘要说明,让用户了解特定类型的通知有多少处于挂起状态。
+
+</p>
+
+<div class="col-6">
+
+<p><strong>禁忌用法</strong></p>
+ <img src="{@docRoot}images/android-5.0/notifications/Summarise_Dont.png" alt="" width="311px" />
+</div>
+
+<div>
+<p><strong>建议用法</strong></p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/Summarise_Do.png" alt="" width="311px" />
+</div>
+
+<p style="clear:left; padding-top:30px; padding-bottom:20px">您可通过使用展开的摘要布局提供有关组成摘要的各个通知的更多详情。
+
+此方法可让用户更好地了解哪些通知处于挂起状态,如果他们有足够的兴趣,还可在相关联的应用中阅读详情。
+
+
+
+</p>
+<div class="col-6">
+ <img src="{@docRoot}images/android-5.0/notifications/Stack.png" style="margin-bottom:20px" alt="" width="311px" />
+ <p class="img-caption">
+ 展开和收起的摘要通知(使用 <code>InboxStyle</code>)
+ </p>
+</div>
+
+<h3 style="clear:both" id="make_notifications_optional">将通知设置为可选
+</h3>
+
+<p>用户应始终能控制通知。允许用户通过将某个通知设置项目添加至您的应用设置,禁用应用的通知或更改其提醒属性,例如警报声和是否使用振动。
+
+
+
+</p>
+
+<h3 id="use_distinct_icons">使用不同的图标</h3>
+<p>通过扫一眼通知区域,用户可以了解哪些类型的通知当前处于挂起状态。
+
+</p>
+
+<div class="figure">
+ <img src="{@docRoot}images/android-5.0/notifications/ProductIcons.png" alt="" width="420" />
+</div>
+
+ <div><p><strong>建议用法</strong></p>
+ <p>查看 Android 应用已经提供的通知图标并为您的应用创建外观明显不同的通知图标。
+
+</p>
+
+ <p><strong>建议用法</strong></p>
+ <p>对小图标使用正确的<a href="/design/style/iconography.html#notification">通知图标样式</a>,对操作图标使用相应的材料灯<a href="/design/style/iconography.html#action-bar">操作栏图标</a>。
+
+
+
+</p>
+<p ><strong>建议用法</strong></p>
+<p >图标外观要简洁清晰,避免使用过于精细、难以辨认的图标。
+</p>
+
+ <div><p><strong>禁忌用法</strong></p>
+ <p>对小图标和操作图标设置任何附加的阿尔法通道属性(变暗或变淡);这些图标会有抗锯齿边缘,但是由于 Android 使用这些图标作为蒙板(即仅使用阿尔法通道),因此通常应以完全不透明的方式绘制图像。
+
+
+
+
+</p>
+
+</div>
+<p style="clear:both"><strong>禁忌用法</strong></p>
+
+<p>利用色彩将您的应用与其他应用区分开来。通知图标应该是纯白透明背景图像。
+</p>
+
+
+<h3 id="pulse_the_notification_led_appropriately">对通知 LED 施加相应的脉冲
+</h3>
+
+<p>许多 Android 设备都配有通知 LED,用于让用户在屏幕关闭时了解事件。
+
+优先级为 <code>MAX</code>、
+<code>HIGH</code> 或 <code>DEFAULT</code> 的通知应让 LED 发光,而优先级较低的通知(<code>LOW</code> 和 <code>MIN</code>)则不应让 LED 发光。
+
+</p>
+
+<p>用户对通知的控制应延伸至 LED。当您使用 DEFAULT_LIGHTS 时,LED 将发出白光。
+
+您的通知不应使用不同的颜色,除非用户明确对其进行了自定义。
+
+</p>
+
+<h2 id="building_notifications_that_users_care_about">构建用户关注的通知
+</h2>
+
+<p>要创建用户喜爱的应用,精心设计通知很重要。通知是应用的代言人,还可增强应用的个性化特征。
+
+
+无用或者不重要的通知会给用户带来烦恼,或者由于过分分散用户的注意力而使其感到愤怒,因此请谨慎使用通知。
+
+
+</p>
+
+<h3 id="when_to_display_a_notification">何时显示通知</h3>
+
+<p>要创建人们乐于使用的应用,就需要认识到用户的注意力和关注点是一种必须予以保护的资源,这一点很重要。
+
+尽管 Android 的通知系统在设计上希望最小化通知对用户注意力的影响,但是仍然要重视通知会中断用户任务流程这一事实。在您计划通知时,要问问自己,它们是否足够重要,是否适合让用户中断手上的任务。
+
+
+
+
+
+
+如果您不确定,可允许用户使用应用的通知设置来选择是否接收通知,或者将通知优先级标志调整为 <code>LOW</code> 或 <code>MIN</code>,从而避免在用户做其他事情时分散他们的注意力。
+
+
+
+</p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/TimeSensitive.png" alt="" width="311px" />
+ <p style="margin-top:10px" class="img-caption">
+ 时间敏感通知的示例
+ </p>
+
+<p>尽管行为良好的应用通常只在用户对其操作后才会发出通知,但在极少数情况下,应用通过无提示的通知形式打断用户也是值得的。
+</p>
+
+<p>将通知主要用于<strong>时间敏感的事件</strong>,尤其是这些同步事件<strong>涉及其他用户时</strong>。
+例如,传入的聊天属于实时同步通信形式:
+
+另一个用户在主动等待您的回应。
+日历事件是使用通知并引起用户注意的另一个好例子,因为事件已经迫近,并且日历事件通常涉及其他人员。
+
+
+</p>
+
+<h3 style="clear:both" id="when_not_to_display_a_notification">何时不显示通知
+</h3>
+
+<div class="figure" style="margin-top:60px">
+ <img src="{@docRoot}images/android-5.0/notifications/AntiSample1.png" alt="" width="311px" />
+</div>
+
+<p>在其他很多情况下都不适合显示通知:</p>
+
+<ul>
+ <li> 不要将并非特定于用户的信息或并非确实时间敏感的信息告知用户。
+
+例如,流经社交网络的异步和未经订阅的更新,通常不适合引发实时中断。
+
+
+对于确实关注它们的用户,可让他们选择接收通知。
+</li>
+ <li> 如果相关的新信息当前显示在屏幕上,则不要创建通知。
+不过可以使用应用本身的 UI 在上下文中将新信息直接告知用户。
+
+
+ 例如,聊天应用不应在用户主动和另一名用户聊天时创建系统通知。
+</li>
+ <li> 对于技术要求不高的操作(例如保存或同步信息或更新应用),如果应用或系统无需用户参与就可解决问题,请不要中断用户。
+
+</li>
+ <li> 如果可以让应用自行恢复错误,而不必让用户采取任何操作,则不要中断用户来告知他们发生此错误。
+
+</li>
+ <li> 请不要创建没有实际通知内容和仅仅是为您的应用做宣传的通知。通知应当提供有用、及时、最新的信息,而不应仅用于推广应用。
+
+
+
+</li>
+ <li> 请不要为了向用户宣传您的品牌而创建过多的通知。
+
+ 此类通知会让用户不满,从而很可能离您而去。提供少量更新信息并让用户保持与您的应用交互的最佳方式是开发一个小工具,让用户可以选择是否将其放在主屏幕上。
+
+
+
+
+</li>
+</ul>
+
+<h2 style="clear:left" id="interacting_with_notifications">与通知交互
+</h2>
+
+<p>通知由状态栏中的图标指示,并且可以通过打开抽屉式通知栏进行访问。
+
+</p>
+
+<p>触摸通知会打开相关联的应用并进入与通知匹配的详细内容。在通知上向左或向右滑动会将其从抽屉式通知栏中删除。
+
+</p>
+
+<h3 id="ongoing_notifications">持续性通知</h3>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/MusicPlayback.png" alt="" width="311px" />
+ <p class="img-caption">
+ 因播放音乐而持续显示的通知
+ </p>
+</div>
+<p>持续性通知可让用户持续了解后台运行的进度。例如,音乐播放器在通知系统中通告当前播放的曲目,并继续进行播放,直至用户停止播放。
+
+
+
+持续性通知也可为持续时间较长的任务(例如下载文件或视频编码之类的任务)向用户显示反馈。
+
+用户无法手动从抽屉式通知栏中删除持续性通知。
+</p>
+
+<h3 id="ongoing_notifications">媒体播放</h3>
+<p>在 Android 5.0 中,锁定屏幕不会为弃用的
+{@link android.media.RemoteControlClient} 类显示传输控件。但是它<em>确实</em>会显示通知,因此每个应用的播放通知现在是用户在锁屏状态控制播放的主要方式。
+
+此行为可让应用更好地控制显示哪些按钮,这样,无论是否锁屏,都可以为用户提供一致的体验。
+
+
+</p>
+
+<h3 style="clear:both"
+id="dialogs_and_toasts_are_for_feedback_not_notification">对话框和 Toast
+</h3>
+
+<p>如果您的应用当前未显示在屏幕上,则不应创建对话框或 Toast。
+对话框或 Toast 应仅限用于即时响应用户在应用内部采取的操作。有关使用对话框和 Toast 的进一步指导,请参阅<a href="/design/patterns/confirming-acknowledging.html">确认和确知</a>。
+
+
+
+</p>
+
+<h3>排名和排序</h3>
+
+<p>通知属于新闻,因此基本以时间倒序显示,并且会特别考虑应用规定的通知<a href="#correctly_set_and_manage_notification_priority">优先级</a>。
+
+
+</p>
+
+<p>通知是锁定屏幕的关键部分,并且在设备显示屏每次亮起时突出显示。
+
+锁定屏幕上的空间有限,因此确定哪些通知最为紧急或最密切相关非常重要。
+
+由于这个原因,Android 在处理通知时使用了更为精密的排序算法,考虑到以下因素:
+
+</p>
+
+<ul>
+ <li> 时间戳以及应用规定的优先级。</li>
+ <li> 通知是否最近以声音或振动形式告知过用户。
+(也就是说,如果手机刚发出了铃声,并且用户希望知道“刚才发生了什么?”,那么锁定屏幕应让用户一眼看到相应的通知。)
+
+
+</li>
+ <li> 与使用 {@link android.app.Notification#EXTRA_PEOPLE} 的通知相关的任何人,尤其是加星标的联系人。
+</li>
+</ul>
+
+<p>为了充分利用此排序功能,请专注于您希望建立的用户体验,而不是拘泥于列表上的某个特定项。
+
+</p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/AntiSample3.png" alt="" width="700px" />
+
+ <p class="img-caption" style="margin-top:10px">Gmail 通知使用的是默认优先级,因此它们的顺序通常低于来自即时通讯应用(例如环聊)的消息,但是在有新邮件送达时会临时占位。
+
+
+
+
+ </p>
+
+
+<h3>在锁定屏幕上</h3>
+
+<p>由于通知在锁定屏幕上可见,所以用户隐私是特别重要的考虑事项。
+
+通知通常包含敏感信息,并且不一定需要让所有拿起设备并打开显示屏的人看到。
+
+</p>
+
+<ul>
+ <li> 对于配置了安全锁定屏幕(PIN 码、图案或密码)的设备,界面分为公用和私人部分。
+公用界面可显示在安全锁定屏幕上,因此任何人都可看见。
+私人界面是锁定屏幕背后的内容,只有在用户登录设备后才会显示。
+</li>
+</ul>
+
+<h3>用户对显示在安全锁定屏幕上的信息的控制</h3>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/LockScreen@2x.png" srcset="{@docRoot}images/android-5.0/notifications/LockScreen.png 1x" alt="" width="311px" />
+ <p class="img-caption">
+ 位于锁定屏幕上的通知,具有用户解锁设备后可显示的内容。
+ </p>
+</div>
+
+<p>在设置安全锁定屏幕时,用户可以选择从安全锁定屏幕隐藏敏感的详细信息。
+在这种情况下,系统 UI 会考虑通知的<em>可见性级别</em>,从而确定哪些内容可以安全地显示出来。
+
+</p>
+<p> 要控制可见性级别,可调用 <code><a
+href="/reference/android/app/Notification.Builder.html#setVisibility(int)">Notification.Builder.setVisibility()</a></code>,然后指定以下值之一:
+
+</p>
+
+<ul>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_PUBLIC">VISIBILITY_PUBLIC</a></code>。显示通知的完整内容。
+
+ 在未指定可见性的情况下,此设置是系统的默认设置。</li>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_PRIVATE">VISIBILITY_PRIVATE</a></code>。在锁定屏幕上,会显示通知的基本信息,包括其图标以及发布此通知的应用名称。
+
+剩下的通知详细信息不会显示。需要注意的一些有用建议如下:
+
+ <ul>
+ <li> 如果您希望为通知提供不同的公用版本,供系统显示在安全锁定屏幕上,可在 <code><a
+href="/reference/android/app/Notification.html#publicVersion">Notification.publicVersion</a></code> 字段中提供替换通知对象。
+
+
+
+ <li> 该设置可让您的应用有机会创建有用内容的删减版本,但是不会显示个人信息。
+可参考短信应用的示例,这种应用的通知包括短信的文本以及发信者的姓名和联系人图标。该通知应为 <code>VISIBILITY_PRIVATE</code>,但是 <code>publicVersion</code> 仍然可以包含“有 3 条新消息”这样的有用信息,而不会提供其他识别性详细信息。
+
+
+
+
+ </ul>
+ </li>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_SECRET">Notification.VISIBILITY_SECRET</a></code>。仅显示最为精简的信息,甚至不包括通知图标。
+</li>
+</ul>
+<h2 style="clear:both" id="notifications_on_android_wear">Android Wear 上的通知
+</h2>
+
+<p>通知及其<em>操作</em>默认会和穿戴设备桥接。开发者可以控制哪些通知会从手机桥接至手表,反之亦然。
+
+
+开发者也可以控制哪些操作会进行桥接。如果您的应用包含无法通过单次点击完成的操作,则可以将这些操作隐藏在您的 Android Wear 设备通知中,或者考虑将它们连接至 Android Wear 设备应用,从而可让用户在其手表上完成操作。
+
+
+
+
+
+</p>
+
+<h4>桥接通知和操作</h4>
+
+<p>连接的设备,例如手机,可将通知桥接至 Android Wear 设备,从而将通知显示在此处。
+与此相似,您也可以桥接操作,从而让用户可在 Android Wear 设备上直接操作通知。
+</p>
+
+<p><strong>桥接</strong></p>
+
+<ul>
+ <li> 新的即时通讯</li>
+ <li> 单次点击操作,例如 +1、赞、收藏</li>
+</ul>
+
+<img src="{@docRoot}images/android-5.0/notifications/WearBasic.png" width="156px" height="156px" alt="" />
+
+<p><strong>不要桥接</strong></p>
+
+<ul>
+ <li> 新收到的播客通知</li>
+ <li> 映射至手表上无法使用的功能的操作</li>
+</ul>
+
+
+
+<p><h4>为 Android Wear 设备定义的独特操作</h4></p>
+
+<p>有些操作只能在 Android Wear 上执行。包括以下情况:</p>
+
+<ul>
+ <li> 例如“马上回来”这样的预设回复快速列表</li>
+ <li> 在手机上打开</li>
+ <li> 调出语音输入屏幕的“评论”或“回复”操作</li>
+ <li> 启动 Android Wear 专用应用的操作</li>
+</ul>
+
+<img src="{@docRoot}images/android-5.0/notifications/ReplyAction.png" width="156px" height="156px" alt="" />
diff --git a/docs/html-intl/intl/zh-cn/preview/api-overview.jd b/docs/html-intl/intl/zh-cn/preview/api-overview.jd
new file mode 100644
index 0000000..c64a38e
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/preview/api-overview.jd
@@ -0,0 +1,521 @@
+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">Hotspot 2.0 第 1 版支持</a></li>
+ <li><a href="#4K-display">4K 显示模式</a></li>
+ <li><a href="#behavior-themeable-colorstatelists">主题化 ColorStateList</a></li>
+ <li><a href="#audio">音频功能</a></li>
+ <li><a href="#video">视频功能</a></li>
+ <li><a href="#camera">相机功能</a>
+ <ol>
+ <li><a href="#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">API 级别 22 至 M 预览版&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>:请不要在 Google Play 商店中发布基于 M 开发者预览版的应用。
+</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 的意向系统。您可以利用此功能将应用与您拥有的某个 Web 域关联。
+平台可以根据此关联确定在处理特定 Web 链接时默认使用的应用,跳过提示用户选择应用的步骤。如需了解如何实现此功能,请参阅<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 密钥库系统</a>结合使用。
+</p>
+
+<h3 id="fingerprint-authentication">指纹身份验证</h3>
+
+<p>如需通过指纹扫描验证用户身份,请获取新增
+{@code android.hardware.fingerprint.FingerprintManager} 类的实例,并调用
+{@code FingerprintManager.authenticate()} 方法。您的应用必须运行在带有指纹传感器的兼容设备上。
+您必须在应用中实现指纹身份验证流的用户界面,并在 UI 中使用标准 Android 指纹图标。<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">示例应用</a>中包含有 Android 指纹图标 ({@code c_fp_40px.png})。请注意,如果您要开发多个使用指纹身份验证的应用,每个应用必须独立验证用户的指纹。
+
+
+
+
+</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 finger touch &lt;finger_id&gt;} 参数的 {@code telnet 127.0.0.1 &lt;emulator-id&gt;} 命令。
+</p>
+</li>
+</ol>
+
+<h3 id="confirm-credential">确认凭据</h3>
+<p>您的应用可以根据用户在多久之前最后一次解锁设备来验证其身份。此功能让用户不必费心记忆应用特定密码,您也无需实现自己的身份验证用户界面。
+
+您的应用应当利用此功能并结合实现公钥或私钥,以进行用户身份验证。
+</p>
+
+<p>如需设置成功验证用户身份后可再次使用同一密钥的超时持续时间,请在设置 {@link javax.crypto.KeyGenerator} 或
+{@link java.security.KeyPairGenerator} 时调用新增的
+{@code android.security.keystore.KeyGenParameterSpec.setUserAuthenticationValidityDurationSeconds()}
+ 方法。
+此功能目前适用于对称加密操作。
+</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 "android.service.chooser.chooser_target_service"} 的
+{@code &lt;meta-data&gt;} 元素。
+</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">Hotspot 2.0 第 1 版支持</h2>
+<p>
+本预览版在 Nexus 6 和 Nexus 9 设备上添加了对 Hotspot 2.0 第 1 版规范的支持。如需在您的应用中设置 Hotspot 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} 属性可指示检测到的网络是否为 Hotspot 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">主题化 ColorStateList</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>通过新增的 {@code android.media.midi} API 提供了对 <a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a>
+ 协议的支持。使用这些 API 可发送和接收 MIDI 事件。
+</li>
+ <li>新增了 {@code android.media.AudioRecord.Builder} 类和 {@code android.media.AudioTrack.Builder}
+ 类,分别用于创建数字音频采集和回放对象,还可用于配置音频源和接收器属性来替代系统默认值。
+</li>
+ <li>用于关联音频和输入设备的 API 钩子。如果您的应用允许用户通过与 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">闪光灯 API</h3>
+<p>如果相机设备带有闪光灯,您可以通过调用 {@code CameraManager.setTorchMode()}
+ 方法,在不打开相机设备的情况下打开或关闭闪光灯的火炬模式。应用对闪光灯或相机设备不享有独占所有权。
+每当相机设备不可用,或者开启火炬的其他相机资源不可用时,火炬模式即会被关闭并变为不可用状态。
+
+其他应用也可调用 {@code setTorchMode()} 来关闭火炬模式。
+当最后一个开启火炬模式的应用关闭时,火炬模式就会被关闭。
+</p>
+
+<p>您可以注册一个回调,通过调用
+{@code CameraManager.registerTorchCallback()} 方法接收有关火炬模式状态的通知。第一次注册回调时,系统会立即调用它,并返回所有当前已知配备闪光灯的相机设备的火炬模式状态。
+
+如果成功开启或关闭火炬模式,系统会调用
+{@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>通过
+{@code DevicePolicyManager.setStatusBarEnabledState()} 方法禁用或重新启用状态栏(包括快速设置、通知以及启动 Google Now 的向上划动手势)。
+</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>:现在,设备所有者可使用 {@link android.content.pm.PackageInstaller}
+ API 在不依赖 Google Play for Work 的情况下静默式安装和卸载应用。
+现在,您可以通过设备所有者配置设备,从而无需用户干预即可获取并安装应用。
+此功能可用于在不激活 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 服务设置应用限制,设备所有者可以指定用于 FRP 解锁的备用 Google 帐户,以替代在设备上激活的 Google 帐户。
+</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>:现在,<strong>设置 &gt; 更多 &gt; VPN</strong> 中会显示 VPN 应用。此外,现在,关于 VPN 使用情况的通知取决于该 VPN 的配置方式。
+
+
+对于配置文件所有者,通知取决于该 VPN 是针对托管配置文件、个人配置文件还是同时针对这两者进行配置。
+对于设备所有者,通知取决于 VPN 是否针对整个设备进行配置。
+</li>
+<li><strong>工作状态通知</strong>:现在,每当来自托管配置文件的应用具有前台活动时,状态栏就会出现一个公文包图标。
+此外,如果设备直接解锁到托管配置文件中某个应用的活动,则会显示一个 Toast,通知用户他们位于托管配置文件内。
+
+
+</li>
+</ul>
+
+<p class="note">
+ 如需详细了解 M 开发者预览版中的所有 API 变更,请参阅 <a href="{@docRoot}preview/download.html">API 差异报告</a>。
+</p>
diff --git a/docs/html-intl/intl/zh-cn/preview/behavior-changes.jd b/docs/html-intl/intl/zh-cn/preview/behavior-changes.jd
new file mode 100644
index 0000000..39494b9
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/preview/behavior-changes.jd
@@ -0,0 +1,402 @@
+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">打盹</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">音频管理器变更</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">API 级别 22 至 M 预览版&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">打盹</h3>
+<p>如果设备未插入电源,并在屏幕关闭后的一段时间内保持不活动状态,则会进入<em>打盹</em>模式,在该模式下设备会尝试让系统保持休眠状态。
+在该模式下,设备会定期短时间恢复正常工作,以便进行应用同步,还可让系统执行任何挂起的操作。
+
+</p>
+
+<p>在打盹模式下,您的应用会受到以下限制:</p>
+<ul>
+<li>网络访问被禁用,除非您的应用获得高优先级 Google Cloud Messaging 操作消息 (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>当设备退出打盹模式时,它会执行任何挂起的作业和同步。</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 Messaging</a> 版本允许您指定高优先级消息。
+如果您的应用收到高优先级 GCM 消息,即使设备处于打盹模式,系统也会向其授予短时间的网络访问权限。
+
+</p>
+
+<p>如需了解在您的应用中测试打盹模式的技巧,请参阅
+<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 Messaging</a> (GCM) 版本允许您指定高优先级消息。
+如果您的应用收到高优先级 GCM 消息,即使其处于空闲状态,也会被授予短时间的网络访问权限。
+
+</p>
+
+<p>如需了解在您的应用中测试应用待机的技巧,请参阅
+<a href="{@docRoot}preview/testing/guide.html#doze-standby">测试指南</a>。
+ </p>
+
+<h2 id="behavior-adoptable-storage">可采用的存储设备</h2>
+<p>
+使用本预览版时,用户可以<em>采用</em> SD 卡等外部存储设备。采用外部存储设备可加密和格式化设备,使其具有类似内部存储设备的行为。
+用户可以利用此特性在存储设备之间移动应用及其私有数据。
+移动应用时,系统会遵守清单文件中的
+<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 驱动器通过一根 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">音频管理器变更</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>现在,当用户在您的应用中选择文本时,您可以在一个<a href="http://www.google.com/design/spec/patterns/selection.html#selection-text-selection" class="external-link">浮动工具栏</a>中显示“剪切”<em></em>、“复制”<em></em>和“粘贴”<em></em>等文本选择操作。
+
+其在用户交互实现上与<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 Support Library</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()},然后对返回的
+{@link android.support.v7.app.AppCompatDelegate} 调用
+{@code android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled()},并将输入参数设置为 {@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>
+在之前的版本中,如果应用利用带有
+{@code disableAllOthers=true} 设置的
+{@link android.net.wifi.WifiManager#enableNetwork(int,boolean) enableNetwork()} 强制设备连接特定 Wi-Fi 网络,设备将会断开与蜂窝数据网络等其他网络的连接。
+在本预览版中,设备不再断开与上述其他网络的连接。如果您的应用的 {@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>
+更改当前用户会导致之前用户帐户拥有的应用内活动相机客户端被驱逐。
+对相机的访问仅限于访问当前设备用户拥有的用户个人资料。举例来说,这意味着,当用户切换到其他帐户后,“来宾”帐户实际上无法让使用相机子系统的进程保持运行状态。
+
+
+</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">
+公开 bug 6670</a>),并且现在已实现了按 {@code soname} 搜索。
+
+
+之前包含错误的 {@code DT_NEEDED} 条目(通常是开发计算机文件系统上的绝对路径)却仍工作正常的应用,如今可能会出现加载失败。
+</p>
+
+<p>现已正确实现 {@code dlopen(3) RTLD_LOCAL} 标志。请注意,
+{@code RTLD_LOCAL} 是默认值,因此不显式使用
+{@code RTLD_LOCAL} 的 {@code dlopen(3)} 调用将受到影响(除非您的应用显式使用 {@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 Dialer Call Log 现在会在用户查看通话记录时显示工作联系人。将 {@code DevicePolicyManager.setCrossProfileCallerIdDisabled()} 设置为 {@code true} 可在 Google Dialer Call Log 中隐藏托管配置文件联系人。
+
+
+仅当您将 {@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/zh-cn/preview/features/runtime-permissions.jd b/docs/html-intl/intl/zh-cn/preview/features/runtime-permissions.jd
new file mode 100644
index 0000000..8e361fb
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/preview/features/runtime-permissions.jd
@@ -0,0 +1,794 @@
+page.title=权限
+page.tags=previewresources, androidm
+page.keywords=permissions, runtime, preview
+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} 的所有权限。
+
+
+ 例如,闹铃和 Internet 权限属于 {@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>应用名称</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> 权限,以便允许其直接访问相机。
+然后,应用将使用 Camera 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(
+<i>permission_name</i>)</code>。即便知道用户已授予该权限,应用也应执行此检查,因为用户可以随时撤销应用的权限。
+
+
+例如,如果用户需要使用应用拍摄照片,则应用将调用
+<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
+ Debug Bridge (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>
+ 例如,摄影应用可能需要使用位置服务,以便能够为照片添加地理标签。
+通常,用户可能不了解照片能够包含位置信息,并且对摄影应用想要了解具体位置感到不解。
+
+因此在这种情况下,应用最好在调用
+<code>requestPermissions()</code> 之前告知此功能的相关信息。<em></em>
+
+</p>
+
+<p>
+ 其中一种办法是将这些请求纳入应用教程。这样,教程可以依次显示应用的每项功能,并在显示每项功能时解释需要哪些相应的权限。
+
+例如,摄影应用的教程可以演示其“与您的联系人共享照片”功能,然后告知用户需要为应用授予权限以便其查看用户的联系人。
+
+
+然后,应用可以调用 <code>requestPermissions()</code>,要求用户提供该访问权限。
+当然,并非所有用户都会按照教程操作,因此您仍需在应用的正常操作期间检查和请求权限。
+
+
+</p>
diff --git a/docs/html-intl/intl/zh-cn/preview/overview.jd b/docs/html-intl/intl/zh-cn/preview/overview.jd
new file mode 100644
index 0000000..cebbf06
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/preview/overview.jd
@@ -0,0 +1,362 @@
+page.title=计划概览
+page.metaDescription=欢迎参加 Android M 开发者预览版计划。此计划将为您提供针对 Android 的下一版本测试和优化应用所需的所有功能。
+page.image=images/cards/card-preview_16-9_2x.png
+page.tags="preview", "developer", "android"
+
+@jd:body
+
+<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(适用于电视)以及模拟器中运行并测试应用。
+
+ </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>
+ 在最初的几周里,我们将优先处理开发者报告的问题,以便尽快测试并提供反馈。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 反馈和支持
+ </h5>
+
+ <p>
+ 使用<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 发布为止。最终的 Android M SDK 将于 2015 年第三季度公众版发布之前不久发布。
+
+
+</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>(第三季度末),为 Android 新版本以及最终的系统行为和功能交付官方 API。
+
+
+</p>
+
+<p>
+ 如果您在 Android M 中进行测试和开发,我们郑重建议您随着预览版更新的发布,<strong>将开发环境保持为相应的最新版本</strong>。
+
+ 为了简化这一过程,我们将为已刷入预览版内部版本的设备提供<strong>空中下载 (OTA) 更新</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 管理器下载这些组件:
+</p>
+
+<ul>
+ <li>M 开发者预览版 <strong>SDK 工具</strong>
+ </li>
+
+ <li>M 开发者预览版<strong>模拟器系统映像</strong>(32 位和 64 位)
+
+ </li>
+
+ <li>适用于 Android TV 的 M 开发者预览版<strong>模拟器系统映像</strong>(32 位)
+
+ </li>
+</ul>
+
+<h4>
+ 硬件系统映像
+</h4>
+
+<p>
+ 您可从<a href="download.html">“下载”页面</a>中下载这些供 Nexus 设备使用的硬件系统映像:
+
+</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>
+ M 开发者预览版当前版本的<a href="{@docRoot}preview/support.html#release-notes">版本说明</a>,包括变更说明和差异报告。
+
+ </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+ 社区。在此社区中,您可<strong>与其他使用 Android M 的开发者建立联系</strong>。您可以共享观察结果或想法,或查找 Android M 问题的解决方法。
+
+
+
+ </li>
+</ul>
+
+
+<h2 id="preview_apis_and_publishing">
+ 锁定目标、预览版 API 和发布
+</h2>
+
+<p>
+ Android M 开发者预览版是仅面向开发的版本,
+<strong>并不具有标准的 API 级别</strong>。如果您想选择拒绝通过兼容性行为测试您的应用(强烈推荐),则可将应用的 <code><a href=
+ "/guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a></code>
+ 设置为 <code>“MNC”</code>,从而锁定 M 开发者预览版。
+
+
+</p>
+
+<p>
+ Android M 开发者预览版提供<strong>预览 API</strong> 功能
+&mdash; 在最终的 SDK 发布之前,这些 API 都不是正式的 API。目前,最终的 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>,刷入 Nexus 5、6、9 和 Player 的最新 M 开发者预览版系统映像。
+
+为开发设备刷入系统映像后,预览版更新将通过无线 (OTA) 更新进行交付。</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/zh-cn/training/basics/activity-lifecycle/index.jd b/docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/index.jd
new file mode 100644
index 0000000..dad2208
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/index.jd
@@ -0,0 +1,72 @@
+page.title=管理Activity生命周期
+page.tags=Activity生命周期
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+
+<h2>依赖项和先决条件</h2>
+<ul>
+ <li>如何创建 Android 项目(请参阅<a href="{@docRoot}training/basics/firstapp/creating-project.html">创建 Android项目</a>)
+</li>
+</ul>
+
+
+<h2>您还应阅读</h2>
+<ul>
+ <li><a href="{@docRoot}guide/components/activities.html">Activity</a></li>
+</ul>
+
+
+<h2>试一试</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">下载演示</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>当用户导航、退出和返回您的应用时,应用中的 {@link android.app.Activity} 实例将在其生命周期中转换不同状态。
+
+例如,当您的Activity初次开始时,它将出现在系统前台并接收用户焦点。
+
+在这个过程中,Android 系统会对Activity调用一系列生命周期方法,通过这些方法,您可以设置用户界面和其他组件。
+如果用户执行开始另一Activity或切换至另一应用的操作,当其进入后台(在其中Activity不再可见,但实例及其状态完整保留),系统会对您的Activity调用另外一系列生命周期方法。
+
+
+</p>
+
+<p>在生命周期回调方法内,您可以声明
+用户离开和再次进入Activity时的Activity行为。比如,如果您正构建流视频播放器,当用户切换至另一应用时,您可能要暂停视频或终止网络连接。当用户返回时,您可以重新连接网络并允许用户从同一位置继续播放视频。
+
+
+</p>
+
+<p>本课讲述每个 {@link
+android.app.Activity} 实例接收的重要生命周期回调方法以及您如何使用这些方法以使您的Activity按照用户预期进行并且当您的Activity不需要它们时不会消耗系统资源。
+</p>
+
+<h2>课程</h2>
+
+<dl>
+ <dt><b><a href="starting.html">开始Activity</a></b></dt>
+ <dd>学习有关Activity生命周期、用户如何启动您的应用以及如何执行基本Activity创建操作的基础知识。
+</dd>
+ <dt><b><a href="pausing.html">暂停和继续Activity</a></b></dt>
+ <dd>学习Activity暂停时(部分隐藏)和继续时的情况以及您应在这些状态变化期间执行的操作。
+</dd>
+ <dt><b><a href="stopping.html">停止和重新开始Activity</a></b></dt>
+ <dd>学习用户完全离开您的Activity并返回到该Activity时发生的情况。</dd>
+ <dt><b><a href="recreating.html">重新创建Activity</a></b></dt>
+ <dd>学习您的Activity被销毁时的情况以及您如何能够根据需要重新构建Activity。
+</dd>
+</dl>
+
diff --git a/docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/pausing.jd b/docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/pausing.jd
new file mode 100644
index 0000000..ef5b0d5
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/pausing.jd
@@ -0,0 +1,147 @@
+page.title=暂停和继续Activity
+page.tags=Activity生命周期
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>本课程将向您展示如何</h2>
+ <ol>
+ <li><a href="#Pause">暂停Activity</a></li>
+ <li><a href="#Resume">继续Activity</a></li>
+ </ol>
+
+ <h2>您还应阅读</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">Activity</a>
+ </li>
+ </ul>
+
+<h2>试一试</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">下载演示</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>在正常使用应用的过程中,前台Activity有时会被其他导致Activity<em>暂停的可视组件阻挡</em>。
+例如,当半透明Activity打开时(比如对话框样式中的Activity),上一个Activity会暂停。
+只要Activity仍然部分可见但目前又未处于焦点之中,它会一直暂停。
+</p>
+
+<p>但是,一旦Activity完全被阻挡并且不可见,它便<em>停止</em>(将在下一堂课中讨论)。
+</p>
+
+<p>当您的Activity进入暂停状态时,系统会对您的 {@link android.app.Activity} 调用 {@link
+android.app.Activity#onPause onPause()} 方法,通过该方法,您可以停止不应在暂停时继续的进行之中的操作(比如视频)或保留任何应该永久保存的信息,以防用户坚持离开应用。如果用户从暂停状态返回到您的Activity,系统会重新开始该Activity并调用
+{@link android.app.Activity#onResume onResume()} 方法。
+
+
+</p>
+
+<p class="note"><strong>注意:</strong>当您的Activity收到对 {@link
+android.app.Activity#onPause()} 的调用时,可能意味着Activity将暂停
+一会,并且用户可能从焦点返回到您的Activity。但这通常意味着用户即将离开您的Activity。
+</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-paused.png" />
+<p class="img-caption"><strong>图 1.</strong>当半透明Activity阻挡您的Activity时,系统会调用 {@link android.app.Activity#onPause onPause()} 并且Activity会在“暂停”状态下等待 (1)。
+
+如果用户在Activity仍然处于暂停状态时返回Activity,则系统会调用 {@link android.app.Activity#onResume onResume()} (2)。
+</p>
+
+
+<h2 id="Pause">暂停Activity</h2>
+
+<p>当系统为您的Activity调用 {@link android.app.Activity#onPause()} 时,它从技术角度看意味着您的Activity仍然处于部分可见状态,但往往说明用户即将离开Activity并且它很快就要进入“停止”状态。
+
+您通常应使用
+ {@link android.app.Activity#onPause()} 回调:</p>
+
+<ul>
+ <li>停止动画或其他可能消耗 CPU 的进行之中的操作。</li>
+ <li>提交未保存的更改,但仅当用户离开时希望永久性保存此类更改(比如电子邮件草稿)。
+</li>
+ <li>释放系统资源,比如广播接收器、传感器手柄(比如 GPS) 或当您的Activity暂停且用户不需要它们时仍然可能影响电池寿命的任何其他资源。
+
+</li>
+</ul>
+
+<p>例如,如果您的应用使用 {@link android.hardware.Camera},
+{@link android.app.Activity#onPause()} 方法是释放它的好位置。</p>
+
+<pre>
+&#64;Override
+public void onPause() {
+ super.onPause(); // Always call the superclass method first
+
+ // Release the Camera because we don't need it when paused
+ // and other activities might need to use it.
+ if (mCamera != null) {
+ mCamera.release()
+ mCamera = null;
+ }
+}
+</pre>
+
+<p>一般情况下,您<strong>不得</strong>使用 {@link android.app.Activity#onPause()} 永久性存储用户更改(比如输入表格的个人信息)。
+只有在您确定用户希望自动保存这些更改的情况(比如,电子邮件草稿)下,才能在 {@link android.app.Activity#onPause()}中永久性存储用户更改。但您应避免在 {@link
+android.app.Activity#onPause()} 期间执行 CPU 密集型工作,比如向数据库写入信息,因为这会拖慢向下一Activity过渡的过程(您应改为在
+{@link android.app.Activity#onStop onStop()}期间执行高负载关机操作。
+
+
+
+</p>
+
+<p>您应通过相对简单的方式在 {@link android.app.Activity#onPause
+onPause()} 方法中完成大量操作,这样才能加快在您的Activity确实停止的情况下用户向下一个目标过渡的速度。
+</p>
+
+<p class="note"><strong>注意:</strong>当您的Activity暂停时,{@link
+android.app.Activity} 实例将驻留在内存中并且在Activity继续时被再次调用。您无需重新初始化在执行任何导致进入“继续”状态的回调方法期间创建的组件。
+
+</p>
+
+
+
+<h2 id="Resume">继续Activity</h2>
+
+<p>当用户从“暂停”状态继续您的Activity时,系统会调用 {@link
+android.app.Activity#onResume()} 方法。</p>
+
+<p>请注意,每当您的Activity进入前台时系统便会调用此方法,包括它初次创建之时。
+同样地,您应实现{@link
+android.app.Activity#onResume()} 初始化您在 {@link
+android.app.Activity#onPause()} 期间释放的组件并且执行每当Activity进入“继续”状态时必须进行的任何其他初始化操作(比如开始动画和初始化只在Activity具有用户焦点时使用的组件)。
+
+</p>
+
+<p>{@link android.app.Activity#onResume()} 的以下示例对应于以上的
+ {@link android.app.Activity#onPause()} 示例,因此它初始化Activity暂停时释放的照相机。
+</p>
+
+<pre>
+&#64;Override
+public void onResume() {
+ super.onResume(); // Always call the superclass method first
+
+ // Get the Camera instance as the activity achieves full user focus
+ if (mCamera == null) {
+ initializeCamera(); // Local method to handle camera init
+ }
+}
+</pre>
+
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/recreating.jd b/docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/recreating.jd
new file mode 100644
index 0000000..a7971d8
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/recreating.jd
@@ -0,0 +1,178 @@
+page.title=重新创建Activity
+page.tags=Activity生命周期
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>本课程将向您展示如何</h2>
+ <ol>
+ <li><a href="#SaveState">保存Activity状态</a></li>
+ <li><a href="#RestoreState">恢复Activity状态</a></li>
+ </ol>
+
+ <h2>您还应阅读</h2>
+ <ul>
+ <li><a href="{@docRoot}training/basics/supporting-devices/screens.html">支持不同屏幕</a>
+</li>
+ <li><a href="{@docRoot}guide/topics/resources/runtime-changes.html">处理运行时更改</a></li>
+ <li><a href="{@docRoot}guide/components/activities.html">Activity</a>
+ </li>
+ </ul>
+
+ </div>
+</div>
+
+<p>在有些情况下,您的Activity会因正常应用行为而销毁,比如当用户按 <em>返回</em>按钮或您的Activity通过调用
+ {@link android.app.Activity#finish()}示意自己的销毁。
+如果Activity当前被停止或长期未使用,或者前台Activity需要更多资源以致系统必须关闭后台进程恢复内存,系统也可能会销毁Activity。
+
+</p>
+
+<p>当您的Activity因用户按了<em>返回</em> 或Activity自行完成而被销毁时,系统的 {@link android.app.Activity} 实例概念将永久消失,因为行为指示不再需要Activity。
+
+但是,如果系统因系统局限性(而非正常应用行为)而销毁Activity,尽管
+{@link android.app.Activity} 实际实例已不在,系统会记住其存在,这样,如果用户导航回实例,系统会使用描述Activity被销毁时状态的一组已保存数据创建Activity的新实例。
+
+
+系统用于恢复先前状态的已保存数据被称为“实例状态”,并且是
+ {@link android.os.Bundle} 对象中存储的键值对集合。
+</p>
+
+<p class="caution"><strong>注意:</strong>每次用户旋转屏幕时,您的Activity将被销毁并重新创建。
+当屏幕方向变化时,系统会销毁并重新创建前台Activity,因为屏幕配置已更改并且您的Activity可能需要加载备用资源(比如布局)。
+
+</p>
+
+<p>默认情况下,系统会使用 {@link android.os.Bundle} 实例状态保存您的Activity布局(比如,输入到 {@link android.widget.EditText} 对象中的文本值)中有关每个 {@link android.view.View} 对象的信息。
+
+这样,如果您的Activity实例被销毁并重新创建,布局状态便恢复为其先前的状态,且您无需代码。
+
+但是,您的Activity可能具有您要恢复的更多状态信息,比如跟踪用户在Activity中进度的成员变量。
+
+</p>
+
+<p class="note"><strong>注意:</strong>为了 Android 系统恢复Activity中视图的状态,<strong>每个视图必须具有</strong>
+<a href="{@docRoot}reference/android/view/View.html#attr_android:id">{@code
+android:id}</a> 属性提供的唯一 ID。
+</p>
+
+<p>要保存有关Activity状态的其他数据,您必须替代
+ {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} 回调方法。当用户要离开Activity并在Activity意外销毁时向其传递将保存的 {@link android.os.Bundle} 对象时,系统会调用此方法。
+
+
+如果系统必须稍后重新创建Activity实例,它会将相同的 {@link
+android.os.Bundle} 对象同时传递给 {@link android.app.Activity#onRestoreInstanceState
+onRestoreInstanceState()} 和 {@link android.app.Activity#onCreate onCreate()}
+方法。
+</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-savestate.png" />
+<p class="img-caption"><strong>图 2.</strong>当系统开始停止您的Activity时,它会
+调用 {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} (1),因此,您可以指定您希望在 {@link android.app.Activity} 实例必须重新创建时保存的额外状态数据。如果Activity被销毁且必须重新创建相同的实例,系统将在 (1) 中定义的状态数据同时传递给 {@link android.app.Activity#onCreate onCreate()} 方法(2) 和 {@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} 方法(3)。
+
+
+
+
+
+</p>
+
+
+
+<h2 id="SaveState">保存Activity状态</h2>
+
+<p>当您的Activity开始停止时,系统会调用 {@link android.app.Activity#onSaveInstanceState
+onSaveInstanceState()} 以便您的Activity可以保存带有键值对集合的状态信息。
+此方法的默认实现保存有关Activity视图层次的状态信息,例如 {@link android.widget.EditText} 小工具中的文本或{@link android.widget.ListView} 的滚动位置。
+
+</p>
+
+<p>要保存Activity的更多状态信息,您必须实现 {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} 并将键值对添加至 {@link android.os.Bundle} 对象。
+
+例如:</p>
+
+<pre>
+static final String STATE_SCORE = "playerScore";
+static final String STATE_LEVEL = "playerLevel";
+...
+
+&#64;Override
+public void onSaveInstanceState(Bundle savedInstanceState) {
+ // Save the user's current game state
+ savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
+ savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
+
+ // Always call the superclass so it can save the view hierarchy state
+ super.onSaveInstanceState(savedInstanceState);
+}
+</pre>
+
+<p class="caution"><strong>注意:</strong>始终调用 {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()} 的超类实现,以便默认实现可以保存视图层次的状态。
+</p>
+
+
+
+<h2 id="RestoreState">恢复Activity状态</h2>
+
+<p>当您的Activity在先前销毁之后重新创建时,您可以从系统向Activity传递的
+{@link android.os.Bundle}
+恢复已保存的状态。{@link android.app.Activity#onCreate onCreate()} 和 {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} 回调方法均接收包含实例状态信息的相同 {@link android.os.Bundle}。
+</p>
+
+<p>因为无论系统正在创建Activity的新实例还是重新创建先前的实例,都会调用 {@link android.app.Activity#onCreate onCreate()} 方法,因此您必须在尝试读取它之前检查状态 {@link android.os.Bundle} 是否为 null。
+
+如果为 null,则系统将创建Activity的新实例,而不是恢复已销毁的先前实例。
+
+</p>
+
+<p>例如,此处显示您如何可以在 {@link android.app.Activity#onCreate
+onCreate()} 中恢复一些状态数据:</p>
+
+<pre>
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState); // Always call the superclass first
+
+ // Check whether we're recreating a previously destroyed instance
+ if (savedInstanceState != null) {
+ // Restore value of members from saved state
+ mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
+ mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
+ } else {
+ // Probably initialize members with default values for a new instance
+ }
+ ...
+}
+</pre>
+
+<p>您可以选择实现系统在 {@link android.app.Activity#onStart()} 方法之后调用的 {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} ,而不是在{@link android.app.Activity#onCreate onCreate()} 期间恢复状态。
+
+系统只在存在要恢复的已保存状态时调用 {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}
+,因此您无需检查 {@link android.os.Bundle} 是否为 null:</p>
+
+<pre>
+public void onRestoreInstanceState(Bundle savedInstanceState) {
+ // Always call the superclass so it can restore the view hierarchy
+ super.onRestoreInstanceState(savedInstanceState);
+
+ // Restore state members from saved instance
+ mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
+ mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
+}
+</pre>
+
+<p class="caution"><strong>注意:</strong>始终调用 {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()} 的超类实现,以便默认实现可以恢复视图层次的状态。
+</p>
+
+<p>要了解更多有关因运行时重启事件(例如屏幕旋转时)而重新创建Activity的信息,请阅读<a href="{@docRoot}guide/topics/resources/runtime-changes.html">处理运行时更改</a>。
+</p>
+
diff --git a/docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/starting.jd b/docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/starting.jd
new file mode 100644
index 0000000..05f9728
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/starting.jd
@@ -0,0 +1,285 @@
+page.title=开始Activity
+page.tags=Activity生命周期
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>本课程将向您展示如何</h2>
+<ol>
+ <li><a href="#lifecycle-states">了解生命周期回调</a></li>
+ <li><a href="#launching-activity">指定您的应用的启动器Activity</a></li>
+ <li><a href="#Create">创建一个新实例</a></li>
+ <li><a href="#Destroy">销毁Activity</a></li>
+</ol>
+
+ <h2>您还应阅读</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">Activity</a></li>
+ </ul>
+
+<h2>试一试</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">下载演示</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>不同于使用 {@code main()} 方法启动应用的其他编程范例,Android 系统会通过调用对应于其生命周期中特定阶段的特定回调方法在 {@link android.app.Activity} 实例中启动代码。
+
+
+有一系列可启动Activity的回调方法,以及一系列可分解Activity的回调方法。
+</p>
+
+<p>本课程概述了最重要的生命周期方法,并向您展示如何处理创建Activity新实例的第一个生命周期回调。
+</p>
+
+
+
+<h2 id="lifecycle-states">了解生命周期回调</h2>
+
+<p>在Activity的生命周期中,系统会按类似于阶梯金字塔的顺序调用一组核心的生命周期方法。
+也就是说,Activity生命周期的每个阶段就是金字塔上的一阶。
+当系统创建新Activity实例时,每个回调方法会将Activity状态向顶端移动一阶。
+金字塔的顶端是Activity在前台运行并且用户可以与其交互的时间点。
+</p>
+
+<p>当用户开始离开Activity时,系统会调用其他方法在金字塔中将Activity状态下移,从而销毁Activity。
+在有些情况下,Activity将只在金字塔中部分下移并等待(比如,当用户切换到其他应用时),Activity可从该点开始移回顶端(如果用户返回到该Activity),并在用户停止的位置继续。
+
+
+</p>
+
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle.png" />
+<p class="img-caption"><strong>图 1.</strong>简化的Activity生命周期图示,以阶梯金字塔表示。
+此图示显示,对于用于将Activity朝顶端的“继续”状态移动一阶的每个回调,有一种将Activity下移一阶的回调方法。
+
+Activity还可以从“暂停”和“停止”状态回到继续状态。
+</p>
+
+
+<p>根据Activity的复杂程度,您可能不需要实现所有生命周期方法。
+但是,了解每个方法并实现确保您的应用按照用户期望的方式运行的方法非常重要。
+正确实现您的Activity生命周期方法可确保您的应用按照以下几种方式良好运行,包括:
+</p>
+<ul>
+ <li>如果用户在使用您的应用时接听来电或切换到另一个应用,它不会崩溃。
+</li>
+ <li>在用户未主动使用它时不会消耗宝贵的系统资源。
+</li>
+ <li>如果用户离开您的应用并稍后返回,不会丢失用户的进度。
+</li>
+ <li>当屏幕在横向和纵向之间旋转时,不会崩溃或丢失用户的进度。
+</li>
+</ul>
+
+<!--
+<p class="table-caption"><strong>Table 1.</strong> Activity lifecycle state pairs and callback
+methods.</p>
+<table>
+ <tr>
+ <th scope="col">Lifecycle State</th>
+ <th scope="col">Startup Method</th>
+ <th scope="col">Teardown Method</th>
+ </tr>
+ <tr>
+ <td>Created / Destroyed</td>
+ <td>{@link android.app.Activity#onCreate onCreate()}</td>
+ <td>{@link android.app.Activity#onDestroy()}</td>
+ </tr>
+ <tr>
+ <td>Started / Stopped</td>
+ <td>{@link android.app.Activity#onStart()}</td>
+ <td>{@link android.app.Activity#onStop()}</td>
+ </tr>
+ <tr>
+ <td>Resumed / Resumed</td>
+ <td>{@link android.app.Activity#onResume()}</td>
+ <td>{@link android.app.Activity#onPause()}</td>
+ </tr>
+</table>
+-->
+
+<p>正如您将要在以下课程中要学习的,有Activity会在图 1 所示不同状态之间过渡的几种情况。
+但是,这些状态中只有三种可以是静态。
+也就是说,Activity只能在三种状态之一下存在很长时间。
+</p>
+<dl>
+ <dt>继续</dt>
+ <dd>在这种状态下,Activity处于前台,且用户可以与其交互。(有时也称为“运行”状态。)
+</dd>
+ <dt>暂停</dt>
+ <dd>在这种状态下,Activity被在前台中处于半透明状态或者未覆盖整个屏幕的另一个Activity&mdash;部分阻挡。
+暂停的Activity不会接收用户输入并且无法执行任何代码。
+
+ <dt>停止</dt>
+ <dd>在这种状态下,Activity被完全隐藏并且对用户不可见;它被视为处于后台。
+停止时,Activity实例及其诸如成员变量等所有状态信息将保留,但它无法执行任何代码。
+</dd>
+</dl>
+
+<p>其他状态(“创建”和“开始”)是瞬态,系统会通过调用下一个生命周期回调方法从这些状态快速移到下一个状态。
+也就是说,在系统调用
+{@link android.app.Activity#onCreate onCreate()} 之后,它会快速调用 {@link
+android.app.Activity#onStart()},紧接着快速调用 {@link
+android.app.Activity#onResume()}。</p>
+
+<p>基本生命周期部分到此为止。现在,您将开始学习特定生命周期行为的一些知识。
+</p>
+
+
+
+<h2 id="launching-activity">指定您的应用的启动器Activity</h2>
+
+<p>当用户从主屏幕选择您的应用图标时,系统会为您已声明为“启动器”( 或“主要”)Activity的应用中的 {@link android.app.Activity} 调用 {@link
+android.app.Activity#onCreate onCreate()} 方法。
+这是作为
+您的应用的用户界面主入口的Activity。</p>
+
+<p>您可以在 Android 宣示说明文件中 <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">{@code AndroidManifest.xml}</a> 定义哪个Activity用作主Activity,该说明文件位于您项目目录的根目录中。
+</p>
+
+<p>您的应用的主Activity必须使用 <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a>(包括 {@link
+android.content.Intent#ACTION_MAIN MAIN} 操作和
+{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} 类别)在宣示说明中声明。例如:</p>
+
+<pre>
+&lt;activity android:name=".MainActivity" android:label="&#64;string/app_name">
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.MAIN" />
+ &lt;category android:name="android.intent.category.LAUNCHER" />
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p class="note"><strong>注意:</strong>当您使用 Android SDK工具创建新 Android 项目时,默认的项目文件包括使用过滤器在宣示说明中声明的 {@link android.app.Activity} 类。
+
+</p>
+
+<p>如果未对您的Activity之一声明 {@link android.content.Intent#ACTION_MAIN MAIN} 操作或
+{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} 类别,那么您的应用图标将不会出现在应用的主屏幕列表中。
+</p>
+
+
+
+<h2 id="Create">创建一个新实例</h2>
+
+<p>大多数应用包含若干个不同的Activity,用户可通过这些Activity执行不同的操作。无论Activity是用户单击您的应用图标时创建的主Activity还是您的应用在响应用户操作时开始的其他Activity,系统都会通过调用其 {@link
+android.app.Activity#onCreate onCreate()} 方法创建 {@link android.app.Activity} 的每个新实例。
+
+
+</p>
+
+<p>您必须实现 {@link android.app.Activity#onCreate onCreate()} 方法执行只应在Activity整个生命周期出现一次的基本
+应用启动逻辑。例如,您的 {@link android.app.Activity#onCreate onCreate()} 的实现应定义用户界面并且可能实例化某些类范围变量。
+
+</p>
+
+<p>例如,{@link android.app.Activity#onCreate onCreate()}
+方法的以下示例显示执行Activity某些基本设置的一些代码,比如声明用户界面(在 XML 布局文件中定义)、定义成员变量,以及配置某些 UI。
+
+</p>
+
+<pre>
+TextView mTextView; // Member variable for text view in the layout
+
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Set the user interface layout for this Activity
+ // The layout file is defined in the project res/layout/main_activity.xml file
+ setContentView(R.layout.main_activity);
+
+ // Initialize member TextView so we can manipulate it later
+ mTextView = (TextView) findViewById(R.id.text_message);
+
+ // Make sure we're running on Honeycomb or higher to use ActionBar APIs
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ // For the main activity, make sure the app icon in the action bar
+ // does not behave as a button
+ ActionBar actionBar = getActionBar();
+ actionBar.setHomeButtonEnabled(false);
+ }
+}
+</pre>
+
+<p class="caution"><strong>注意:</strong>使用 {@link android.os.Build.VERSION#SDK_INT}
+可防止旧版系统以这种方式仅在 Android 2.0 (API 级别5)和更高级别执行新 API 工作。
+较旧版本会遇到运行时异常。</p>
+
+<p>一旦 {@link android.app.Activity#onCreate onCreate()} 完成执行操作,系统会相继调用 {@link android.app.Activity#onStart()} 和 {@link android.app.Activity#onResume()} 方法。
+
+您的Activity从不会驻留在“已创建”或“已开始”状态。在技术上,Activity会在 {@link android.app.Activity#onStart()} 被调用时变得可见,但紧接着是
+{@link android.app.Activity#onResume()},且Activity保持“继续”状态,直到有事情发生使其发生变化,比如当接听来电时,用户导航至另一个Activity,或设备屏幕关闭。
+
+
+</p>
+
+<p>在接下来的其他课程中,您将看到其他Activity如何启动方法,当用于从“暂停”或“停止”状态继续Activity时,{@link
+android.app.Activity#onStart()} 和 {@link android.app.Activity#onResume()} 在您的Activity生命周期中特别有用。
+</p>
+
+<p class="note"><strong>注意:</strong>{@link android.app.Activity#onCreate onCreate()}
+方法包括一个称为 <code>savedInstanceState</code> 的参数,将在有关<a href="recreating.html">重新创建Activity</a>的后续课程中讨论该参数。
+</p>
+
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-create.png" />
+<p class="img-caption"><strong>图 2.</strong>Activity生命周期结构的另一个图示,其重点放在
+创建Activity的新实例时系统依次调用的三大回调上:{@link android.app.Activity#onCreate onCreate()}、{@link
+android.app.Activity#onStart()} 和 {@link android.app.Activity#onResume()}。
+一旦这一系列回调完成,Activity就进入“继续”状态,此时用户可与Activity进行交互,直至用户切换到其他Activity。
+
+</p>
+
+
+
+
+
+
+
+<h2 id="Destroy">销毁Activity</h2>
+
+<p>当Activity的第一个生命周期回调是 {@link android.app.Activity#onCreate
+onCreate()} 时,它最近的回调是 {@link android.app.Activity#onDestroy}。系统会对您的Activity调用此方法,作为您的Activity实例完全从系统内存删除的最终信号。
+
+</p>
+
+<p>大多数应用不需要实现此方法,因为本地类引用与Activity一同销毁,并且您的Activity应在 {@link
+android.app.Activity#onPause} 和 {@link android.app.Activity#onStop} 期间执行大多数清理操作。
+但是,如果您的Activity包含您在 {@link
+android.app.Activity#onCreate onCreate()} 期间创建的后台线程或其他如若未正确关闭可能导致内存泄露的长期运行资源,您应在 {@link
+android.app.Activity#onDestroy} 期间终止它们。
+
+</p>
+
+<pre>
+&#64;Override
+public void onDestroy() {
+ super.onDestroy(); // Always call the superclass
+
+ // Stop method tracing that the activity started during onCreate()
+ android.os.Debug.stopMethodTracing();
+}
+</pre>
+
+<p class="note"><strong>注意:</strong>在所有情况下,系统在调用 {@link android.app.Activity#onPause} 和 {@link
+android.app.Activity#onStop} 之后都会调用 {@link android.app.Activity#onDestroy}
+,只有一个例外:当您从 {@link android.app.Activity#onCreate onCreate()}
+ 方法内调用 {@link
+android.app.Activity#finish()} 时。在有些情况下,比如当您的Activity作为临时决策工具运行以启动另一个Activity时,您可从 {@link
+android.app.Activity#onCreate onCreate()} 内调用 {@link android.app.Activity#finish()} 来销毁Activity。
+在这种情况下,系统会立刻调用 {@link android.app.Activity#onDestroy},而不调用任何其他 生命周期方法。
+
+</p>
diff --git a/docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/stopping.jd b/docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/stopping.jd
new file mode 100644
index 0000000..630817c
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/training/basics/activity-lifecycle/stopping.jd
@@ -0,0 +1,187 @@
+page.title=停止并重新开始Activity
+page.tags=Activity生命周期
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>本课程将向您展示如何</h2>
+ <ol>
+ <li><a href="#Stop">停止Activity</a></li>
+ <li><a href="#Start">开始/重新开始Activity</a></li>
+ </ol>
+
+ <h2>您还应阅读</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">Activity</a>
+ </li>
+ </ul>
+
+<h2>试一试</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">下载演示</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>正确停止和重新开始Activity是Activity生命周期中的重要过程,其可确保您的用户知晓应用始终保持Activity状态并且不会丢失进度。有几种Activity停止和重新开始的关键场景:
+
+</p>
+
+<ul>
+ <li>用户打开“最近应用”窗口并从您的应用切换到另一个应用。当前位于前台的您的应用中的Activity将停止。
+如果用户从主屏幕启动器图标或“最近应用”窗口返回到您的应用,Activity会重新开始。
+</li>
+ <li>用户在您的应用中执行开始新Activity的操作。当第二个Activity创建好后,当前Activity便停止。
+如果用户之后按了<em>返回</em>按钮,第一个Activity会重新开始。
+</li>
+ <li>用户在其手机上使用您的应用的同时接听来电。</li>
+</ul>
+
+<p>{@link android.app.Activity} 课程提供两种生命周期方法:{@link
+android.app.Activity#onStop()} 和 {@link android.app.Activity#onRestart()},这些方法允许您专门处理正在停止和重新开始的Activity。
+不同于识别部分 UI 阻挡的暂停状态,停止状态保证 UI 不再可见,且用户的焦点在另外的Activity(或完全独立的应用)中。
+
+</p>
+
+<p class="note"><strong>注意:</strong>因为系统在停止时会将您的 {@link android.app.Activity}
+实例保留在系统内存中,您根本无需实现
+{@link android.app.Activity#onStop()} 和 {@link android.app.Activity#onRestart()}或甚至{@link
+android.app.Activity#onStart()} 方法。对于大多数相对简单的Activity而言, Activity将停止并重新开始,并且您可能只需使用 {@link
+android.app.Activity#onPause()} 暂停正在进行的操作,并从系统资源断开连接。
+</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-stopped.png" />
+<p class="img-caption"><strong>图 1.</strong>用户离开Activity时,系统会调用 {@link android.app.Activity#onStop onStop()} 停止Activity(1)。
+如果用户在Activity停止时返回,系统会调用 {@link android.app.Activity#onRestart onRestart()}
+(2),紧接着调用 {@link android.app.Activity#onStart onStart()} (3) 和 {@link
+android.app.Activity#onResume()} (4)。
+注意:无论什么场景导致Activity停止,系统始终会在调用 {@link
+android.app.Activity#onStop onStop()} 之前调用 {@link android.app.Activity#onPause onPause()}。
+</p>
+
+
+
+<h2 id="Stop">停止Activity</h2>
+
+<p>当您的Activity收到 {@link android.app.Activity#onStop()} 方法的调用时,它不再可见,并且应释放几乎所有用户不使用时不需要的资源。
+
+一旦您的Activity停止,如果需要恢复系统内存,系统可能会销毁该实例。
+在极端情况下,系统可能会仅终止应用进程,而不会调用Activity的最终 {@link android.app.Activity#onDestroy()} 回调,因此您使用 {@link android.app.Activity#onStop()} 释放可能泄露内存的资源非常重要。
+
+</p>
+
+<p>尽管 {@link android.app.Activity#onPause onPause()} 方法在
+{@link android.app.Activity#onStop()}之前调用,您应使用 {@link android.app.Activity#onStop onStop()}
+执行更大、占用更多 CPU 的关闭操作,比如向数据库写入信息。
+</p>
+
+<p>例如,此处是将草稿笔记内容保存在永久存储中的 {@link android.app.Activity#onStop onStop()} 的实现:
+</p>
+
+<!-- TODO: Find a better example for onStop, because this kind of thing should probably use a
+separate thread but that's too complicated to show here. -->
+<pre>
+&#64;Override
+protected void onStop() {
+ super.onStop(); // Always call the superclass method first
+
+ // Save the note's current draft, because the activity is stopping
+ // and we want to be sure the current note progress isn't lost.
+ ContentValues values = new ContentValues();
+ values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
+ values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());
+
+ getContentResolver().update(
+ mUri, // The URI for the note to update.
+ values, // The map of column names and new values to apply to them.
+ null, // No SELECT criteria are used.
+ null // No WHERE columns are used.
+ );
+}
+</pre>
+
+<p>当您的Activity停止时, {@link android.app.Activity} 对象将驻留在内存中并在Activity继续时被再次调用。
+您无需重新初始化在任何导致进入“继续”状态的回调方法过程中创建的组件。
+系统还会在布局中跟踪每个 {@link android.view.View} 的当前状态,如果用户在 {@link android.widget.EditText} 小工具中输入文本,该内容会保留,因此您无需保存即可恢复它。
+
+
+</p>
+
+<p class="note"><strong>注意:</strong>即使系统在Activity停止时销毁了Activity,它仍会保留 {@link android.os.Bundle}(键值对的二进制大对象)中的 {@link android.view.View} 对象(比如 {@link
+android.widget.EditText} 中的文本),并在用户导航回Activity的相同实例时恢复它们 (<a href="recreating.html">下一堂课</a> 讲述更多有关在您的Activity被销毁且重新创建的情况下使用 {@link android.os.Bundle} 保存其他数据状态的知识)。
+
+
+</p>
+
+
+
+<h2 id="Start">开始/重新开始Activity</h2>
+
+<p>当您的Activity从停止状态返回前台时,它会接收对
+{@link android.app.Activity#onRestart()} 的调用。系统还会在每次您的Activity变为可见时调用 {@link
+android.app.Activity#onStart()} 方法(无论是正重新开始还是初次创建)。
+但是,只会在Activity从停止状态继续时调用 {@link
+android.app.Activity#onRestart()} 方法,因此您可以使用它执行只有在Activity之前停止但未销毁的情况下可能必须执行的特殊恢复工作。
+
+</p>
+
+<p>应用需要使用 {@link android.app.Activity#onRestart()} 恢复Activity状态的情况并不常见,因此没有适用于一般应用群体的任何方法指导原则。
+
+但是,因为您的 {@link android.app.Activity#onStop()}
+方法应基本清理所有Activity的资源,您将需要在Activity重新开始时重新实例化它们。
+但是,您还需要在您的Activity初次创建时重新实例化它们(没有Activity的现有实例)。
+出于此原因,您应经常使用 {@link android.app.Activity#onStart()} 回调方法作为
+ {@link android.app.Activity#onStop()} 方法的对应部分,因为系统会在它创建您的Activity以及从停止状态重新开始Activity时调用 {@link
+android.app.Activity#onStart()} 。
+
+</p>
+
+<p>例如,因为用户可能在回到它之前已离开应用很长时间, {@link android.app.Activity#onStart()} 方法是确认所需系统功能已启动的理想选择:
+
+</p>
+
+<pre>
+&#64;Override
+protected void onStart() {
+ super.onStart(); // Always call the superclass method first
+
+ // The activity is either being restarted or started for the first time
+ // so this is where we should make sure that GPS is enabled
+ LocationManager locationManager =
+ (LocationManager) getSystemService(Context.LOCATION_SERVICE);
+ boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
+
+ if (!gpsEnabled) {
+ // Create a dialog here that requests the user to enable GPS, and use an intent
+ // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action
+ // to take the user to the Settings screen to enable GPS when they click "OK"
+ }
+}
+
+&#64;Override
+protected void onRestart() {
+ super.onRestart(); // Always call the superclass method first
+
+ // Activity being restarted from stopped state
+}
+</pre>
+
+
+
+
+<p>当系统销毁您的Activity时,它会调用您的 {@link android.app.Activity} 的 {@link android.app.Activity#onDestroy()}
+方法。因为您通常应已使用 {@link android.app.Activity#onStop()} 释放大多数您的资源,到您接收对 {@link
+android.app.Activity#onDestroy()} 的调用时,大多数应用无需做太多操作。
+此方法是您清理可导致内存泄露的资源的最后一种方法,因此您应确保其他线程被销毁且其他长期运行的操作(比如方法跟踪)也会停止。
+
+
+</p>
+
diff --git a/docs/html-intl/intl/zh-cn/training/basics/data-storage/databases.jd b/docs/html-intl/intl/zh-cn/training/basics/data-storage/databases.jd
new file mode 100644
index 0000000..a6c9193
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/training/basics/data-storage/databases.jd
@@ -0,0 +1,317 @@
+page.title=在 SQL 数据库中保存数据
+page.tags=数据存储
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>本课程将向您展示如何</h2>
+<ol>
+ <li><a href="#DefineContract">定义架构和契约</a></li>
+ <li><a href="#DbHelper">使用 SQL 辅助工具创建数据库</a></li>
+ <li><a href="#WriteDbRow">将信息输入到数据库</a></li>
+ <li><a href="#ReadDbRow">从数据库读取信息</a></li>
+ <li><a href="#DeleteDbRow">从数据库删除信息</a></li>
+ <li><a href="#UpdateDbRow">更新数据库</a></li>
+</ol>
+
+<h2>您还应阅读</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#db">使用数据库</a></li>
+</ul>
+
+<!--
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/Sample.zip" class="button">Download the sample</a>
+ <p class="filename">Sample.zip</p>
+</div>
+-->
+
+</div>
+</div>
+
+
+<p>将数据保存到数据库对于重复或结构化数据(比如契约信息)
+而言是理想之选。本课程假定您基本熟悉 SQL 数据库并且可帮助您开始在 Android 中使用 SQLite 数据库。
+
+您在 Android 中使用数据库所需的 API 在 {@link android.database.sqlite} 软件包中提供。
+</p>
+
+
+<h2 id="DefineContract">定义架构和契约</h2>
+
+<p>SQL 数据库的主要原则之一是架构:数据库如何组织的正式声明。
+架构体现于您用于创建数据库的 SQL
+语句。您会发现它有助于创建伴随类,即<em>契约</em> 类,其以一种系统性、自记录的方式明确指定您的架构布局。
+
+</p>
+
+<p>契约类是用于定义 URI、表格和列名称的常数的容器。
+契约类允许您跨同一软件包中的所有其他类使用相同的常数。
+您可以在一个位置更改列名称并使其在您整个代码中传播。
+</p>
+
+<p>组织契约类的一种良好方法是将对于您的整个数据库而言是全局性的定义放入类的根级别。
+然后为枚举其列的每个表格创建内部类。
+</p>
+
+<p class="note"><strong>注意:</strong>通过实现 {@link
+android.provider.BaseColumns} 接口,您的内部类可继承调用的主键字段{@code _ID} ,某些 Android 类(比如光标适配器)将需要内部类拥有该字段。
+
+这并非必需项,但可帮助您的数据库与 Android 框架协调工作。
+</p>
+
+<p>例如,该代码段定义了单个表格的表格名称和列名称:
+</p>
+
+
+<pre>
+public final class FeedReaderContract {
+ // To prevent someone from accidentally instantiating the contract class,
+ // give it an empty constructor.
+ public FeedReaderContract() {}
+
+ /* Inner class that defines the table contents */
+ public static abstract class FeedEntry implements BaseColumns {
+ public static final String TABLE_NAME = &quot;entry&quot;;
+ public static final String COLUMN_NAME_ENTRY_ID = &quot;entryid&quot;;
+ public static final String COLUMN_NAME_TITLE = &quot;title&quot;;
+ public static final String COLUMN_NAME_SUBTITLE = &quot;subtitle&quot;;
+ ...
+ }
+}
+</pre>
+
+
+
+<h2 id="DbHelper">使用 SQL 辅助工具创建数据库</h2>
+
+<p>在您定义了数据库的外观后,您应实现创建和维护数据库和表格的方法。
+这里有一些典型的表格创建和删除语句:
+</P>
+
+<pre>
+private static final String TEXT_TYPE = &quot; TEXT&quot;;
+private static final String COMMA_SEP = &quot;,&quot;;
+private static final String SQL_CREATE_ENTRIES =
+ &quot;CREATE TABLE &quot; + FeedEntry.TABLE_NAME + &quot; (&quot; +
+ FeedEntry._ID + &quot; INTEGER PRIMARY KEY,&quot; +
+ FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP +
+ FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
+ ... // Any other options for the CREATE command
+ &quot; )&quot;;
+
+private static final String SQL_DELETE_ENTRIES =
+ &quot;DROP TABLE IF EXISTS &quot; + FeedEntry.TABLE_NAME;
+</pre>
+
+<p>就像您在设备的<a href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">内部存储</a>中保存文件那样,Android 将您的数据库保存在私人磁盘空间,即关联的应用。
+
+您的数据是安全的,因为在默认情况下,其他应用无法访问此区域。
+</p>
+
+<p>{@link
+android.database.sqlite.SQLiteOpenHelper} 类中有一组有用的 API。当您使用此类获取对您数据库的引用时,系统将只在需要之时而不是 <em>应用启动</em>过程中执行可能长期运行的操作:创建和更新数据库。
+
+
+
+您只需调用
+{@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase} 或
+{@link android.database.sqlite.SQLiteOpenHelper#getReadableDatabase}。</p>
+
+<p class="note"><strong>注意:</strong>由于它们可能长期运行,因此请确保您在后台线程中调用 {@link
+android.database.sqlite.SQLiteOpenHelper#getWritableDatabase} 或 {@link
+android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} ,
+比如使用 {@link android.os.AsyncTask} 或 {@link android.app.IntentService}。
+</p>
+
+<p>要使用 {@link android.database.sqlite.SQLiteOpenHelper},请创建一个
+替代 {@link
+android.database.sqlite.SQLiteOpenHelper#onCreate onCreate()}、{@link
+android.database.sqlite.SQLiteOpenHelper#onUpgrade onUpgrade()} 和 {@link
+android.database.sqlite.SQLiteOpenHelper#onOpen onOpen()} 回调方法的子类。您可能还希望实现 {@link android.database.sqlite.SQLiteOpenHelper#onDowngrade onDowngrade()},
+但这并非必需操作。
+</p>
+
+<p>例如,这里有一个使用如上所示一些命令的 {@link
+android.database.sqlite.SQLiteOpenHelper} 的实现:</p>
+
+<pre>
+public class FeedReaderDbHelper extends SQLiteOpenHelper {
+ // If you change the database schema, you must increment the database version.
+ public static final int DATABASE_VERSION = 1;
+ public static final String DATABASE_NAME = &quot;FeedReader.db&quot;;
+
+ public FeedReaderDbHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL(SQL_CREATE_ENTRIES);
+ }
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // This database is only a cache for online data, so its upgrade policy is
+ // to simply to discard the data and start over
+ db.execSQL(SQL_DELETE_ENTRIES);
+ onCreate(db);
+ }
+ public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ onUpgrade(db, oldVersion, newVersion);
+ }
+}
+</pre>
+
+<p>要访问您的数据库,请实例化 {@link
+android.database.sqlite.SQLiteOpenHelper} 的子类:</p>
+
+<pre>
+FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());
+</pre>
+
+
+
+
+<h2 id="WriteDbRow">将信息输入到数据库</h2>
+
+<p>通过将一个 {@link android.content.ContentValues}
+对象传递至 {@link android.database.sqlite.SQLiteDatabase#insert insert()} 方法将数据插入数据库:</p>
+
+<pre>
+// Gets the data repository in write mode
+SQLiteDatabase db = mDbHelper.getWritableDatabase();
+
+// Create a new map of values, where column names are the keys
+ContentValues values = new ContentValues();
+values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id);
+values.put(FeedEntry.COLUMN_NAME_TITLE, title);
+values.put(FeedEntry.COLUMN_NAME_CONTENT, content);
+
+// Insert the new row, returning the primary key value of the new row
+long newRowId;
+newRowId = db.insert(
+ FeedEntry.TABLE_NAME,
+ FeedEntry.COLUMN_NAME_NULLABLE,
+ values);
+</pre>
+
+<p>{@link android.database.sqlite.SQLiteDatabase#insert insert()}
+的第一个参数即为表格名称。第二个参数指定在
+{@link android.content.ContentValues} 为空的情况下框架可在其中插入 NULL 的列的名称(如果您将其设置为 {@code "null"},
+那么框架将不会在没有值时插入行。)
+</p>
+
+
+
+
+<h2 id="ReadDbRow">从数据库读取信息</h2>
+
+<p>要从数据库中读取信息,请使用 {@link android.database.sqlite.SQLiteDatabase#query query()}
+方法,将其传递至选择条件和所需列。该方法结合 {@link android.database.sqlite.SQLiteDatabase#insert insert()}
+和 {@link android.database.sqlite.SQLiteDatabase#update update()} 的元素,除非列列表定义了您希望获取的数据,而不是希望插入的数据。
+
+查询的结果将在
+ {@link android.database.Cursor} 对象中返回给您。</p>
+
+<pre>
+SQLiteDatabase db = mDbHelper.getReadableDatabase();
+
+// Define a <em>projection</em> that specifies which columns from the database
+// you will actually use after this query.
+String[] projection = {
+ FeedEntry._ID,
+ FeedEntry.COLUMN_NAME_TITLE,
+ FeedEntry.COLUMN_NAME_UPDATED,
+ ...
+ };
+
+// How you want the results sorted in the resulting Cursor
+String sortOrder =
+ FeedEntry.COLUMN_NAME_UPDATED + " DESC";
+
+Cursor c = db.query(
+ FeedEntry.TABLE_NAME, // The table to query
+ projection, // The columns to return
+ selection, // The columns for the WHERE clause
+ selectionArgs, // The values for the WHERE clause
+ null, // don't group the rows
+ null, // don't filter by row groups
+ sortOrder // The sort order
+ );
+</pre>
+
+<p>要查看游标中的某一行,请使用 {@link android.database.Cursor} 移动方法之一,您必须在开始读取值之前始终调用这些方法。
+一般情况下,您应通过调用 {@link android.database.Cursor#moveToFirst} 开始,其将“读取位置”置于结果中的第一个条目中。
+
+对于每一行,您可以通过调用
+{@link android.database.Cursor} 获取方法之一读取列的值,比如 {@link android.database.Cursor#getString
+getString()} 或 {@link android.database.Cursor#getLong getLong()}。对于每种获取方法,您必须传递所需列的索引位置,您可以通过调用
+{@link android.database.Cursor#getColumnIndex getColumnIndex()} 或
+{@link android.database.Cursor#getColumnIndexOrThrow getColumnIndexOrThrow()} 获取。例如:
+
+</p>
+
+<pre>
+cursor.moveToFirst();
+long itemId = cursor.getLong(
+ cursor.getColumnIndexOrThrow(FeedEntry._ID)
+);
+</pre>
+
+
+
+
+<h2 id="DeleteDbRow">从数据库删除信息</h2>
+
+<p>要从表格中删除行,您需要提供识别行的选择条件。
+数据库 API 提供了一种机制,用于创建防止 SQL 注入的选择条件。
+该机制将选择规范划分为选择子句和选择参数。
+该子句定义要查看的列,还允许您合并列测试。
+
+参数是根据捆绑到子句的项进行测试的值。由于结果并未按照与常规 SQL 语句相同的方式进行处理,它不受 SQL 注入的影响。
+
+</p>
+
+<pre>
+// Define 'where' part of query.
+String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + &quot; LIKE ?&quot;;
+// Specify arguments in placeholder order.
+String[] selectionArgs = { String.valueOf(rowId) };
+// Issue SQL statement.
+db.delete(table_name, selection, selectionArgs);
+</pre>
+
+
+
+<h2 id="UpdateDbRow">更新数据库</h2>
+
+<p>当您需要修改数据库值的子集时,请使用 {@link
+android.database.sqlite.SQLiteDatabase#update update()} 方法。</p>
+
+<p>更新表格可将{@link
+android.database.sqlite.SQLiteDatabase#insert insert()} 的内容值句法与
+ {@link android.database.sqlite.SQLiteDatabase#delete delete()} 的 {@code where} 句法相结合。</p>
+
+<pre>
+SQLiteDatabase db = mDbHelper.getReadableDatabase();
+
+// New value for one column
+ContentValues values = new ContentValues();
+values.put(FeedEntry.COLUMN_NAME_TITLE, title);
+
+// Which row to update, based on the ID
+String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + &quot; LIKE ?&quot;;
+String[] selectionArgs = { String.valueOf(rowId) };
+
+int count = db.update(
+ FeedReaderDbHelper.FeedEntry.TABLE_NAME,
+ values,
+ selection,
+ selectionArgs);
+</pre>
+
diff --git a/docs/html-intl/intl/zh-cn/training/basics/data-storage/files.jd b/docs/html-intl/intl/zh-cn/training/basics/data-storage/files.jd
new file mode 100644
index 0000000..1442275
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/training/basics/data-storage/files.jd
@@ -0,0 +1,379 @@
+page.title=保存文件
+page.tags=数据存储
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>本课程将向您展示如何</h2>
+<ol>
+ <li><a href="#InternalVsExternalStorage">选择内部或外部存储</a></li>
+ <li><a href="#GetWritePermission">获取外部存储的权限</a></li>
+ <li><a href="#WriteInternalStorage">将文件保存在内部存储中</a></li>
+ <li><a href="#WriteExternalStorage">将文件保存在外部存储中</a></li>
+ <li><a href="#GetFreeSpace">查询可用空间</a></li>
+ <li><a href="#DeleteFile">删除文件</a></li>
+</ol>
+
+<h2>您还应阅读</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">使用内部存储</a>
+</li>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#filesExternal">使用外部存储</a>
+</li>
+</ul>
+
+</div>
+</div>
+
+<p>Android 使用与其他平台上基于磁盘的文件系统类似的文件系统。
+本课程讲述如何使用 Android 文件系统通过 {@link java.io.File}
+API 读取和写入文件。
+</p>
+
+<p>{@link java.io.File} 对象适合按照从开始到结束的顺序不跳过地读取或写入大量数据。
+例如,它适合于图像文件或通过网络交换的任何内容。
+</p>
+
+<p>本课程展示如何在您的应用中执行基本的文件相关任务。本课程假定您熟悉 Linux 文件系统的基础知识和 {@link java.io} 中的标准文件输入/输出 API。
+
+</p>
+
+
+<h2 id="InternalVsExternalStorage">选择内部或外部存储</h2>
+
+<p>所有 Android 设备都有两个文件存储区域:“内部”和“外部”存储。这些名称在 Android 早期产生,当时大多数设备都提供内置的非易失性内存(内部存储),以及移动存储介质,比如微型 SD 卡(外部存储)。一些设备将永久性存储空间划分为“内部”和“外部”分区,即便没有移动存储介质,也始终有两个存储空间,并且无论外部存储设备是否可移动,API 的行为均一致。以下列表汇总了关于各个存储空间的实际信息。
+
+
+
+
+
+</p>
+
+<div class="col-5" style="margin-left:0">
+<p><b>内部存储:</b></p>
+<ul>
+<li>它始终可用。</li>
+<li>默认情况下只有您的应用可以访问此处保存的文件。</li>
+<li>当用户卸载您的应用时,系统会从内部存储中删除您的应用的所有文件。
+</li>
+</ul>
+<p>当您希望确保用户或其他应用均无法访问您的文件时,内部存储是最佳选择。
+</p>
+</div>
+
+<div class="col-7" style="margin-right:0">
+<p><b>外部存储:</b></p>
+<ul>
+<li>它并非始终可用,因为用户可采用 USB 存储的形式装载外部存储,并在某些情况下会从设备中将其删除。
+</li>
+<li>它是全局可读的,因此此处保存的文件可能不受您控制地被读取。
+</li>
+<li>当用户卸载您的应用时,只有在您通过 {@link android.content.Context#getExternalFilesDir
+getExternalFilesDir()} 将您的应用的文件保存在目录中时,系统才会从此处删除您的应用的文件。
+</li>
+</ul>
+<p>对于无需访问限制以及您希望与其他应用共享或允许用户使用电脑访问的文件,外部存储是最佳位置。
+
+</p>
+</div>
+
+
+<p class="note" style="clear:both">
+<strong>提示</strong>:尽管应用默认安装在内部存储中,但您可在您的宣示说明中指定 <a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code
+android:installLocation}</a> 属性,这样您的应用便可安装在在外部存储中。
+
+当 APK 非常大且它们的外部存储空间大于内部存储时,用户更青睐这个选择。
+如需了解详细信息,请参阅<a href="{@docRoot}guide/topics/data/install-location.html">应用安装位置</a>。
+</p>
+
+
+<h2 id="GetWritePermission">获取外部存储的权限</h2>
+
+<p>要向外部存储写入信息,您必须在您的<a href="{@docRoot}guide/topics/manifest/manifest-intro.html">宣示说明文件</a>中请求
+ {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} 权限。</p>
+
+<pre>
+&lt;manifest ...>
+ &lt;uses-permission android:name=&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot; /&gt;
+ ...
+&lt;/manifest>
+</pre>
+
+<div class="caution"><p><strong>注意:</strong>
+目前,所有应用都可以读取外部存储,而无需特别的权限。
+但这在将来版本中会进行更改。如果您的应用需要读取外部存储(但不向其写入信息),那么您将需要声明 {@link
+android.Manifest.permission#READ_EXTERNAL_STORAGE} 权限。
+要确保您的应用继续正常工作,您应在更改生效前声明此权限。
+</p>
+<pre>
+&lt;manifest ...>
+ &lt;uses-permission android:name=&quot;android.permission.READ_EXTERNAL_STORAGE&quot; /&gt;
+ ...
+&lt;/manifest>
+</pre>
+<p>但是,如果您的应用使用 {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}
+权限,那么它也隐含读取外部存储的权限。</p>
+</div>
+
+<p>您无需任何权限,即可在内部存储中保存文件。
+您的应用始终具有在其内部存储目录中进行读写的权限。
+</p>
+
+
+
+
+
+<h2 id="WriteInternalStorage">将文件保存在内部存储中</h2>
+
+<p>在内部存储中保存文件时,您可以通过调用以下两种方法之一获取作为
+{@link java.io.File} 的相应目录:</p>
+
+<dl>
+ <dt>{@link android.content.Context#getFilesDir}</dt>
+ <dd>返回表示您的应用的内部目录的 {@link java.io.File} 。</dd>
+ <dt>{@link android.content.Context#getCacheDir}</dt>
+ <dd>返回表示您的应用临时缓存文件的内部目录的 {@link java.io.File} 。
+务必删除所有不再需要的文件并对在指定时间您使用的内存量实现合理大小限制,比如,1MB。
+
+如果在系统即将耗尽存储,它会在不进行警告的情况下删除您的缓存文件。
+</dd>
+</dl>
+
+<p>要在这些目录之一中新建文件,您可以使用 {@link
+java.io.File#File(File,String) File()} 构造函数,传递指定您的内部存储目录的上述方法之一所提供的 {@link java.io.File}
+。例如:</p>
+
+<pre>
+File file = new File(context.getFilesDir(), filename);
+</pre>
+
+<p>或者,您可以调用 {@link
+android.content.Context#openFileOutput openFileOutput()} 获取写入到内部目录中的文件的 {@link java.io.FileOutputStream}
+。例如,此处显示如何向文件写入一些文本:
+</p>
+
+<pre>
+String filename = "myfile";
+String string = "Hello world!";
+FileOutputStream outputStream;
+
+try {
+ outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
+ outputStream.write(string.getBytes());
+ outputStream.close();
+} catch (Exception e) {
+ e.printStackTrace();
+}
+</pre>
+
+<p>或者,如果您需要缓存某些文件,您应改用 {@link
+java.io.File#createTempFile createTempFile()}。例如,以下方法从 {@link java.net.URL} 提取文件名并在您的应用的内部缓存目录中以该名称创建文件:
+
+</p>
+
+<pre>
+public File getTempFile(Context context, String url) {
+ File file;
+ try {
+ String fileName = Uri.parse(url).getLastPathSegment();
+ file = File.createTempFile(fileName, null, context.getCacheDir());
+ catch (IOException e) {
+ // Error while creating file
+ }
+ return file;
+}
+</pre>
+
+<p class="note"><strong>注意:</strong>
+您的应用的内部存储设备目录由您的应用在Android 文件系统特定位置中的软件包名称指定。在技术上,如果您将文件模式设置为可读,另一个应用可以读取您的内部文件。
+
+
+但是,另一个应用也需要知道您的应用的软件包名称和文件名。
+其他应用无法浏览您的内部目录并且没有读写权限,除非您明确将文件设置为可读或可写。
+只要您为内部存储上的文件使用 {@link android.content.Context#MODE_PRIVATE},
+其他应用便从不会访问它们。
+</p>
+
+
+
+
+
+<h2 id="WriteExternalStorage">将文件保存在外部存储中</h2>
+
+<p>由于外部存储可能不可用&mdash;比如,当用户已将存储装载到电脑或已移除提供外部存储的 SD 卡时&mdash;因此,在访问它之前,您应始终确认其容量。
+
+您可以通过调用 {@link android.os.Environment#getExternalStorageState} 查询外部存储状态。
+如果返回的状态为 {@link android.os.Environment#MEDIA_MOUNTED},那么您可以对您的文件进行读写。
+
+例如,以下方法对于确定存储可用性非常有用:
+</p>
+
+<pre>
+/* Checks if external storage is available for read and write */
+public boolean isExternalStorageWritable() {
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+ return false;
+}
+
+/* Checks if external storage is available to at least read */
+public boolean isExternalStorageReadable() {
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
+ }
+ return false;
+}
+</pre>
+
+<p>尽管外部存储可被用户和其他应用进行修改,但您可在此处保存两类文件:
+</p>
+
+<dl>
+ <dt>公共文件</dt>
+ <dd>应供其他应用和用户自由使用的文件。
+当用户卸载您的应用时,用户应仍可以使用这些文件。
+
+ <p>例如,您的应用拍摄的照片或其他已下载的文件。</p>
+ </dd>
+ <dt>私有文件</dt>
+ <dd>本属于您的应用且应在用户卸载您的应用时删除的文件。尽管这些文件在技术上可被用户和其他应用访问(因为它们在外部存储上),它们是实际上不向您的应用之外的用户提供值的文件。当用户卸载您的应用时,系统会删除应用外部专用目录中的所有文件。
+
+
+
+
+ <p>例如,您的应用下载的其他资源或临时介质文件。</p>
+ </dd>
+</dl>
+
+<p>如果您要使用外部存储上的公共文件,请使用
+{@link android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()} 方法获取表示外部存储上相应目录的 {@link java.io.File}
+。该方法使用指定
+您想要保存以便它们可以与其他公共文件在逻辑上组织在一起的文件类型的参数,比如 {@link android.os.Environment#DIRECTORY_MUSIC} 或 {@link
+android.os.Environment#DIRECTORY_PICTURES}。
+例如:</p>
+
+<pre>
+public File getAlbumStorageDir(String albumName) {
+ // Get the directory for the user's public pictures directory.
+ File file = new File(Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES), albumName);
+ if (!file.mkdirs()) {
+ Log.e(LOG_TAG, "Directory not created");
+ }
+ return file;
+}
+</pre>
+
+
+<p>如果您要保存您的应用专用文件,您可以通过调用 {@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()} 获取相应的目录并向其传递指示您想要的目录类型的名称。
+
+通过这种方法创建的各个目录将添加至封装您的应用的所有外部存储文件的父目录,当用户卸载您的应用时,系统会删除这些文件。
+
+</p>
+
+<p>例如,您可以使用以下方法来创建个人相册的目录:</p>
+
+<pre>
+public File getAlbumStorageDir(Context context, String albumName) {
+ // Get the directory for the app's private pictures directory.
+ File file = new File(context.getExternalFilesDir(
+ Environment.DIRECTORY_PICTURES), albumName);
+ if (!file.mkdirs()) {
+ Log.e(LOG_TAG, "Directory not created");
+ }
+ return file;
+}
+</pre>
+
+<p>如果没有适合您文件的预定义子目录名称,您可以改为调用 {@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()} 并传递 {@code null}。这将返回外部存储上您的应用的专用目录
+的根目录。</p>
+
+<p>切记,{@link android.content.Context#getExternalFilesDir getExternalFilesDir()}
+在用户卸载您的应用时删除的目录内创建目录。如果您正保存的文件应在用户卸载您的应用后仍然可用&mdash;比如,当您的应用是照相机并且用户要保留照片时&mdash;您应改用 {@link android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()}。
+
+
+</p>
+
+
+<p>无论您对于共享的文件使用 {@link
+android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()} 还是对您的应用专用文件使用
+{@link android.content.Context#getExternalFilesDir
+getExternalFilesDir()} ,您使用诸如
+{@link android.os.Environment#DIRECTORY_PICTURES} 的 API 常数提供的目录名称非常重要。
+这些目录名称可确保系统正确处理文件。
+例如,保存在 {@link
+android.os.Environment#DIRECTORY_RINGTONES} 中的文件由系统介质扫描程序归类为铃声,而不是音乐。
+</p>
+
+
+
+
+<h2 id="GetFreeSpace">查询可用空间</h2>
+
+<p>如果您事先知道您将保存的数据量,您可以查出是否有足够的可用空间,而无需调用 {@link java.io.File#getFreeSpace} 或 {@link
+java.io.File#getTotalSpace} 引起 {@link
+java.io.IOException} 。
+这些方法分别提供目前的可用空间和存储卷中的总空间。
+此信息也可用来避免填充存储卷以致超出特定阈值。
+</p>
+
+<p>但是,系统并不保证您可以写入与 {@link java.io.File#getFreeSpace}
+指示的一样多的字节。如果返回的数字比您要保存的数据大小大出几 MB,或如果文件系统所占空间不到 90%,则可安全继续操作。否则,您可能不应写入存储。
+
+
+</p>
+
+<p class="note"><strong>注意:</strong>保存您的文件之前,您无需检查可用空间量。
+您可以尝试立刻写入文件,然后在 {@link java.io.IOException} 出现时将其捕获。
+如果您不知道所需的确切空间量,您可能需要这样做。
+例如,如果在保存文件之前通过将 PNG 图像转换成JPEG 更改了文件的编码,您事先将不知道文件的大小。
+
+</p>
+
+
+
+
+<h2 id="DeleteFile">删除文件</h2>
+
+<p>您应始终删除不再需要的文件。删除文件最直接的方法是让打开的文件参考自行调用 {@link java.io.File#delete}。
+</p>
+
+<pre>
+myFile.delete();
+</pre>
+
+<p>如果文件保存在内部存储中,您还可以请求 {@link android.content.Context} 通过调用 {@link android.content.Context#deleteFile deleteFile()} 来定位和删除文件:
+</p>
+
+<pre>
+myContext.deleteFile(fileName);
+</pre>
+
+<div class="note">
+<p><strong>注意:</strong>当用户卸载您的应用时,Android 系统会删除以下各项:
+</p>
+<ul>
+<li>您保存在内部存储中的所有文件</li>
+<li>您使用 {@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()} 保存在外部存储中的所有文件。</li>
+</ul>
+<p>但是,您应手动删除使用
+{@link android.content.Context#getCacheDir()} 定期创建的所有缓存文件并且定期删除不再需要的其他文件。
+</p>
+</div>
+
diff --git a/docs/html-intl/intl/zh-cn/training/basics/data-storage/index.jd b/docs/html-intl/intl/zh-cn/training/basics/data-storage/index.jd
new file mode 100644
index 0000000..6918227
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/training/basics/data-storage/index.jd
@@ -0,0 +1,57 @@
+page.title=保存数据
+page.tags=数据存储、文件、SQL、数据库、首选项
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>依赖项和先决条件</h2>
+<ul>
+ <li>Android 1.6(API 级别 4)或更高</li>
+ <li>熟悉地图键值集合</li>
+ <li>熟悉 Java 文件 I/O API</li>
+ <li>熟悉 SQL 数据库</li>
+</ul>
+
+<h2>您还应阅读</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html">存储选项</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>大多数 Android 应用需要保存数据,即使仅保存在 {@link android.app.Activity#onPause onPause()} 过程中与应用状态有关的信息,以便用户进度不会丢失 。
+大多数非平凡应用也需要保存用户设置,并且有些应用必须在文件和数据库中管理大量的信息。
+
+本课向您介绍 Android 中的主要数据存储选项,包括:
+</p>
+
+<ul>
+ <li>在共享的首选项文件中保存简单数据类型的键值对
+</li>
+ <li>在 Android 的文件系统中保存任意文件</li>
+ <li>使用 SQLite 管理的数据库</li>
+</ul>
+
+
+<h2>课程</h2>
+
+<dl>
+ <dt><b><a href="shared-preferences.html">保存键值集</a></b></dt>
+ <dd>学习使用在键值对中存储少量信息的共享首选项文件。
+</dd>
+
+ <dt><b><a href="files.html">保存文件</a></b></dt>
+ <dd>学习保存基本文件,比如存储一般按顺序读取的较长数据序列 。
+</dd>
+
+ <dt><b><a href="databases.html">在 SQL 数据库中保存数据</a></b></dt>
+ <dd>学习使用 SQLite 数据库读写结构化数据。</dd>
+
+</dl>
diff --git a/docs/html-intl/intl/zh-cn/training/basics/data-storage/shared-preferences.jd b/docs/html-intl/intl/zh-cn/training/basics/data-storage/shared-preferences.jd
new file mode 100644
index 0000000..c10ece8
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/training/basics/data-storage/shared-preferences.jd
@@ -0,0 +1,120 @@
+page.title=保存键值集
+page.tags=数据存储
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>本课程将向您展示如何</h2>
+<ol>
+ <li><a href="#GetSharedPreferences">获取共享首选项的句柄</a></li>
+ <li><a href="#WriteSharedPreference">写入共享首选项</a></li>
+ <li><a href="#ReadSharedPreference">从共享首选项读取信息</a></li>
+</ol>
+
+<h2>您还应阅读</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#pref">使用共享首选项</a></li>
+</ul>
+
+</div>
+</div>
+
+
+<p>如果您有想要保存的相对较小键值集合,您应使用 {@link android.content.SharedPreferences} API。
+{@link android.content.SharedPreferences} 对象指向包含键值对的文件并提供读写这些文件的简单方法。
+
+每个
+{@link android.content.SharedPreferences} 文件由框架进行管理并且可以专用或共享。
+</p>
+
+<p>本课向您展示如何使用 {@link android.content.SharedPreferences} API 存储和检索简单的值。
+</p>
+
+<p class="note"><strong>注意:</strong>{@link android.content.SharedPreferences} API 仅用于读写键值对,您不得将其与
+{@link android.preference.Preference} API 混淆,后者帮助您为您的应用设置构建用户界面(尽管它们使用 {@link android.content.SharedPreferences} 作为其实现以保存应用设置)。
+
+
+有关使用 {@link
+android.preference.Preference} API 的信息,请参阅<a href="{@docRoot}guide/topics/ui/settings.html">设置</a>指南。</p>
+
+<h2 id="GetSharedPreferences">获取共享首选项的句柄</h2>
+
+<p>您可以通过调用以下两种方法之一创建新的共享首选项文件或访问现有的文件:
+</p>
+<ul>
+ <li>{@link android.content.Context#getSharedPreferences(String,int)
+getSharedPreferences()} &mdash; 如果您需要按照您用第一个参数指定的名称识别的多个共享首选项文件,请使用此方法。
+您可以从您的应用中的任何
+{@link android.content.Context} 调用此方法。</li>
+ <li>{@link android.app.Activity#getPreferences(int) getPreferences()} &mdash; 如果您只需使用Activity的一个共享首选项,请从
+{@link android.app.Activity} 中使用此方法。
+因为此方法会检索属于该Activity的默认共享首选项文件,您无需提供名称。
+</li>
+</ul>
+
+<p>例如,以下代码在 {@link android.app.Fragment} 内执行。它访问通过资源字符串
+ {@code R.string.preference_file_key} 识别的共享首选项文件并且使用专用模式打开它,从而仅允许您的应用访问文件。
+
+</p>
+
+<pre>
+Context context = getActivity();
+SharedPreferences sharedPref = context.getSharedPreferences(
+ getString(R.string.preference_file_key), Context.MODE_PRIVATE);
+</pre>
+
+<p>命名您的共享首选项文件时,您应使用对于您的应用而言唯一可识别的名称,比如 {@code "com.example.myapp.PREFERENCE_FILE_KEY"}
+</p>
+
+<p>或者,如果您只需Activity的一个共享首选项文件,您可以使用
+{@link android.app.Activity#getPreferences(int) getPreferences()} 方法:</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+</pre>
+
+<p class="caution"><strong>注意:</strong>如果您创建带 {@link android.content.Context#MODE_WORLD_READABLE} 或 {@link
+android.content.Context#MODE_WORLD_WRITEABLE} 的共享首选项文件,那么知道文件标识符
+的任何其他应用都可以访问您的数据。
+</p>
+
+
+<h2 id="WriteSharedPreference">写入共享首选项</h2>
+
+<p>要写入共享首选项文件, 请通过对您的 {@link android.content.SharedPreferences} 调用 {@link
+android.content.SharedPreferences#edit} 来创建一个 {@link
+android.content.SharedPreferences.Editor}。</p>
+
+<p>传递您想要使用诸如 {@link
+android.content.SharedPreferences.Editor#putInt putInt()} 和 {@link
+android.content.SharedPreferences.Editor#putString putString()} 方法写入的键和值。然后调用 {@link
+android.content.SharedPreferences.Editor#commit} 以保存更改。例如:</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+SharedPreferences.Editor editor = sharedPref.edit();
+editor.putInt(getString(R.string.saved_high_score), newHighScore);
+editor.commit();
+</pre>
+
+
+<h2 id="ReadSharedPreference">从共享首选项读取信息</h2>
+
+<p>要从共享首选项文件中检索值,请调用诸如 {@link
+android.content.SharedPreferences#getInt getInt()} 和 {@link
+android.content.SharedPreferences#getString getString()} 等方法,为您想要的值提供键,并根据需要提供要在键不存在的情况下返回的默认值。
+
+例如:</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+int defaultValue = getResources().getInteger(R.string.saved_high_score_default);
+long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue);
+</pre>
+
diff --git a/docs/html-intl/intl/zh-cn/training/basics/intents/filters.jd b/docs/html-intl/intl/zh-cn/training/basics/intents/filters.jd
new file mode 100644
index 0000000..4bcbdf9
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/training/basics/intents/filters.jd
@@ -0,0 +1,236 @@
+page.title=允许其他应用开始您的Activity
+page.tags=意向
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>本课程将向您展示如何</h2>
+<ol>
+ <li><a href="#AddIntentFilter">添加意向过滤器</a></li>
+ <li><a href="#HandleIntent">处理您的Activity中的意向</a></li>
+ <li><a href="#ReturnResult">返回结果</a></li>
+</ol>
+
+<h2>您还应阅读</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">共享简单数据</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">共享文件</a>
+</ul>
+ </div>
+</div>
+
+<p>前两课重点讲述一方面:从您的应用开始另一个应用的Activity。但如果您的应用可以执行对另一个应用可能有用的操作,您的应用应准备好响应来自其他应用的操作请求。
+
+例如,如果您构建一款可与用户的好友分享消息或照片的社交应用,您最关注的是支持 {@link android.content.Intent#ACTION_SEND} 意向以便用户可以从另一应用发起
+“共享”操作并且启动您的应用执行该操作。
+
+</p>
+
+<p>要允许其他应用开始您的Activity,您需要 <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> 元素。</p>
+
+<p>当您的应用安装在设备上时,系统会识别您的意向过滤器并添加信息至所有已安装应用支持的意向内部目录。当应用通过隐含意向调用 {@link android.app.Activity#startActivity
+startActivity()} 或 {@link android.app.Activity#startActivityForResult startActivityForResult()} 时,系统会找到可以响应该意向的Activity。
+
+
+
+</p>
+
+
+
+<h2 id="AddIntentFilter">添加意向过滤器</h2>
+
+<p>为了正确定义您的Activity可处理的意向,您添加的每个意向过滤器在操作类型和Activity接受的数据方面应尽可能具体。
+
+</p>
+
+<p>如果Activity具有满足以下 {@link android.content.Intent} 对象条件的意向过滤器,系统可能向Activity发送给定的 {@link android.content.Intent}:
+</p>
+
+<dl>
+ <dt>操作</dt>
+ <dd>对要执行的操作命名的字符串。通常是平台定义的值之一,比如
+ {@link android.content.Intent#ACTION_SEND} 或 {@link android.content.Intent#ACTION_VIEW}。
+ <p>使用 <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code &lt;action&gt;}</a> 元素在您的意向过滤器中指定此值。您在此元素中指定的值必须是操作的完整字符串名称,而不是 API 常数(请参阅以下示例)。
+
+</p></dd>
+
+ <dt>数据</dt>
+ <dd>与意向关联的数据描述。
+ <p>用 <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data&gt;}</a> 元素在您的意向过滤器中指定此内容。使用此元素中的一个或多个属性,您可以只指定 MIME 类型、URI 前缀、URI 架构或这些的组合以及其他指示所接受数据类型的项。
+
+
+</p>
+ <p class="note"><strong>注意:</strong>如果您无需声明关于数据的具体信息
+{@link android.net.Uri}(比如,您的Activity处理其他类型的“额外”数据而不是 URI 的时间),您应只指定 {@code android:mimeType} 属性声明您的Activity处理的数据类型,比如 {@code text/plain} 或 {@code image/jpeg}。
+
+</p>
+</dd>
+ <dt>类别</dt>
+ <dd>提供另外一种表征处理意向的Activity的方法,通常与用户手势或Activity开始的位置有关。
+系统支持多种不同的类别,但大多数都很少使用。
+但是,所有隐含意向默认使用
+{@link android.content.Intent#CATEGORY_DEFAULT} 进行定义。
+ <p>用 <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code &lt;category&gt;}</a>
+ 元素在您的意向过滤器中指定此内容。</p></dd>
+</dl>
+
+<p>在您的意向过滤器中,您可以通过声明嵌套在 <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter&gt;}</a>
+元素中的具有相应 XML 元素的各项,来声明您的Activity接受的条件。
+</p>
+
+<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;data android:mimeType="image/*"/>
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p>每个入站意向仅指定一项操作和一个数据类型,但可以在每个
+<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"> {@code
+&lt;intent-filter&gt;}</a> 中声明
+ <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> 和 <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code
+&lt;data&gt;}</a> 元素的多个实例。</p>
+
+<p>如果任何两对操作和数据的行为相斥,您应创建单独的意向过滤器指定与哪种数据类型配对时哪些操作可接受。
+
+</p>
+
+<p>比如,假定您的Activity同时处理 {@link
+android.content.Intent#ACTION_SEND} 和 {@link
+android.content.Intent#ACTION_SENDTO} 意向的文本和图像。在这种情况下,您必须为两个操作定义两种不同的意向过滤器,因为 {@link
+android.content.Intent#ACTION_SENDTO} 意向必须使用数据 {@link android.net.Uri} 指定使用 {@code send} 或 {@code sendto} URI 架构的收件人地址。
+
+例如:</p>
+
+<pre>
+&lt;activity android:name="ShareActivity">
+ &lt;!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.SENDTO"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:scheme="sms" />
+ &lt;data android:scheme="smsto" />
+ &lt;/intent-filter>
+ &lt;!-- filter for sending text or images; accepts SEND action and text or image data -->
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.SEND"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:mimeType="image/*"/>
+ &lt;data android:mimeType="text/plain"/>
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p class="note"><strong>注意:</strong>为了接收隐含意向,您必须在意向过滤器中包含
+{@link android.content.Intent#CATEGORY_DEFAULT} 类别。方法 {@link
+android.app.Activity#startActivity startActivity()} 和 {@link
+android.app.Activity#startActivityForResult startActivityForResult()} 就像声明 {@link android.content.Intent#CATEGORY_DEFAULT} 类别那样处理所有意向。
+如果您不在意向过滤器中声明它,则没有隐含意向分解为您的Activity。
+</p>
+
+<p>如需了解有关发送和接收 {@link android.content.Intent#ACTION_SEND}
+执行社交共享行为的意向的详细信息,请参阅有关<a href="{@docRoot}training/sharing/receive.html">从其他应用接收简单数据</a>的课程。</p>
+
+
+<h2 id="HandleIntent">处理您的Activity中的意向</h2>
+
+<p>为了决定在您的Activity执行哪种操作,您可读取用于开始Activity的 {@link
+android.content.Intent}。</p>
+
+<p>当您的Activity开始时,调用 {@link android.app.Activity#getIntent()} 检索开始Activity的
+{@link android.content.Intent}。您可以在Activity生命周期的任何时间执行此操作,但您通常应在早期回调时(比如,
+{@link android.app.Activity#onCreate onCreate()} 或 {@link android.app.Activity#onStart()})执行。
+</p>
+
+<p>例如:</p>
+
+<pre>
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.main);
+
+ // Get the intent that started this activity
+ Intent intent = getIntent();
+ Uri data = intent.getData();
+
+ // Figure out what to do based on the intent type
+ if (intent.getType().indexOf("image/") != -1) {
+ // Handle intents with image data ...
+ } else if (intent.getType().equals("text/plain")) {
+ // Handle intents with text ...
+ }
+}
+</pre>
+
+
+<h2 id="ReturnResult">返回结果</h2>
+
+<p>如果您想要向调用您的Activity的Activity返回结果,只需调用 {@link
+android.app.Activity#setResult(int,Intent) setResult()} 指定结果代码和结果 {@link
+android.content.Intent}。当您的操作完成且用户应返回原始Activity时,调用 {@link android.app.Activity#finish()} 关闭(和销毁)您的Activity。
+例如:
+</p>
+
+<pre>
+// Create intent to deliver some kind of result data
+Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");
+setResult(Activity.RESULT_OK, result);
+finish();
+</pre>
+
+<p>您必须始终为结果指定结果代码。通常,它为 {@link
+android.app.Activity#RESULT_OK} 或 {@link android.app.Activity#RESULT_CANCELED}。您之后可以根据需要为
+ {@link android.content.Intent} 提供额外的数据。</p>
+
+<p class="note"><strong>注意:</strong>结果默认设置为 {@link
+android.app.Activity#RESULT_CANCELED}。因此,如果用户在完成操作动作或设置结果之前按了<em>返回</em>按钮,原始Activity会收到“已取消”的结果。
+
+</p>
+
+<p>如果您只需返回指示若干结果选项之一的整数,您可以将结果代码设置为大于 0 的任何值。
+如果您使用结果代码传递整数,并且您无需包含 {@link android.content.Intent},您可以调用 {@link
+android.app.Activity#setResult(int) setResult()} 并且仅传递结果代码。
+例如:</p>
+
+<pre>
+setResult(RESULT_COLOR_RED);
+finish();
+</pre>
+
+<p>在这种情况下,只有几个可能的结果,因此结果代码是一个本地定义的整数(大于 0)。
+当您向自己应用中的Activity返回结果时,这将非常有效,因为接收结果的Activity可引用公共常数来确定结果代码的值。
+
+</p>
+
+<p class="note"><strong>注意:</strong>无需检查您的Activity是使用
+ {@link
+android.app.Activity#startActivity startActivity()} 还是 {@link
+android.app.Activity#startActivityForResult startActivityForResult()} 开始的。如果开始您的Activity的意向可能需要结果,只需调用 {@link
+android.app.Activity#setResult(int,Intent) setResult()}。
+如果原始Activity已调用 {@link
+android.app.Activity#startActivityForResult startActivityForResult()},则系统将向其传递您提供给 {@link android.app.Activity#setResult(int,Intent) setResult()} 的结果;否则,会忽略结果。
+
+</p>
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/zh-cn/training/basics/intents/index.jd b/docs/html-intl/intl/zh-cn/training/basics/intents/index.jd
new file mode 100644
index 0000000..3c27581
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/training/basics/intents/index.jd
@@ -0,0 +1,62 @@
+page.title=与其他应用交互
+page.tags=意向、Activity
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>依赖项和先决条件</h2>
+<ul>
+ <li>Activity生命周期基础知识(请参阅<a href="{@docRoot}training/basics/activity-lifecycle/index.html">管理Activity生命周期</a>)
+</li>
+</ul>
+
+
+<h2>您还应阅读</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">共享简单数据</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">共享文件</a>
+ <li><a href="http://android-developers.blogspot.com/2009/11/integrating-application-with-intents.html">
+将应用与意向集成(博客文章)</a></li>
+ <li><a href="{@docRoot}guide/components/intents-filters.html">意向和意向过滤器</a>
+</li>
+</ul>
+
+</div>
+</div>
+
+<p>Android 应用一般具有若干个<a href="{@docRoot}guide/components/activities.html">Activity</a>。每个Activity显示一个用户界面,用户可通过该界面执行特定任务(比如,查看地图或拍照)。要将用户从一个Activity转至另一Activity,您的应用必须使用 {@link
+android.content.Intent} 定义您的应用做某事的“意向”。
+
+当您使用诸如
+{@link
+android.app.Activity#startActivity startActivity()} 的方法将 {@link android.content.Intent} 传递至系统时,系统会使用 {@link
+android.content.Intent} 识别和启动相应的应用组件。使用意向甚至可以让您的应用开始另一个应用中包含的Activity。
+</p>
+
+<p>{@link android.content.Intent} 可以为 <em>显式</em> 以便启动特定组件(特定的 {@link android.app.Activity} 实例)或<em>隐式</em> 以便启动处理意向操作(比如“拍摄照片”)的任何组件。
+
+</p>
+
+<p>本课程您向展示如何使用 {@link android.content.Intent} 执行与其他应用的一些基本交互操作,比如启动另一个应用、接收来自该应用的结果以及使您的应用能够响应来自其他应用的意向。
+
+</p>
+
+<h2>课程</h2>
+
+<dl>
+ <dt><b><a href="sending.html">向另一个应用发送用户</a></b></dt>
+ <dd>显示您如何创建可执行操作的其他应用的隐含意向。
+</dd>
+ <dt><b><a href="result.html">获取Activity的结果</a></b></dt>
+ <dd>显示如何开始另一Activity并接收该Activity的结果。</dd>
+ <dt><b><a href="filters.html">允许其他应用开始您的Activity</a></b></dt>
+ <dd>显示如何通过定义声明您的应用接受的隐含意向的意向过滤器使您的应用中的Activity可供其他应用使用。
+</dd>
+</dl>
+
diff --git a/docs/html-intl/intl/zh-cn/training/basics/intents/result.jd b/docs/html-intl/intl/zh-cn/training/basics/intents/result.jd
new file mode 100644
index 0000000..35b2673
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/training/basics/intents/result.jd
@@ -0,0 +1,178 @@
+page.title=获取Activity的结果
+page.tags=意向
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>本课程将向您展示如何</h2>
+<ol>
+ <li><a href="#StartActivity">开始Activity</a></li>
+ <li><a href="#ReceiveResult">接收结果</a></li>
+</ol>
+
+<h2>您还应阅读</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">共享简单数据</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">共享文件</a>
+</ul>
+
+ </div>
+</div>
+
+<p>开始并不一定是单向的另一个Activity。您还可以开始另一个Activity并
+接收返回的结果。要接收结果,请调用 {@link android.app.Activity#startActivityForResult
+startActivityForResult()}(而不是 {@link android.app.Activity#startActivity
+startActivity()})。</p>
+
+<p>例如,您的应用可启动照相机应用并接收拍摄的照片作为结果。或者,您可以启动“联系人”应用以便用户选择联系人,并且您将接收联系人详细信息作为结果。
+
+</p>
+
+<p>当然,响应的Activity必须设计为返回结果。当它这样做时,它会作为另一
+ {@link android.content.Intent} 对象发送结果。您的Activity在
+{@link android.app.Activity#onActivityResult onActivityResult()} 回调中接收它。</p>
+
+<p class="note"><strong>注意:</strong>当您调用
+{@link android.app.Activity#startActivityForResult startActivityForResult()} 时,您可以使用明确或隐含意向。当开始您自己的Activity以接收结果时,您应使用明确意向确保您可收到预期结果。
+
+</p>
+
+
+<h2 id="StartActivity">开始Activity</h2>
+
+<p> 开始针对结果的Activity时,您所使用的 {@link android.content.Intent} 对象并没有什么特别之处,但您需要向 {@link
+android.app.Activity#startActivityForResult startActivityForResult()} 方法传递额外的整数参数。
+</p>
+
+<p>该整数参数是识别您的请求的“请求代码”。当您收到结果{@link android.content.Intent} 时,回调提供相同的请求代码,以便您的应用可以正确识别结果并确定如何处理它。
+
+</p>
+
+<p>例如,此处显示如何开始允许用户选择联系人的Activity:</p>
+
+<pre>
+static final int PICK_CONTACT_REQUEST = 1; // The request code
+...
+private void pickContact() {
+ Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
+ pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
+ startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
+}
+</pre>
+
+
+<h2 id="ReceiveResult">接收结果</h2>
+
+<p>当用户完成后续Activity并且返回时,系统会调用您的Activity
+{@link android.app.Activity#onActivityResult onActivityResult()} 的方法。此方法包括三个参数:
+</p>
+
+<ul>
+ <li>您向 {@link
+android.app.Activity#startActivityForResult startActivityForResult()} 传递的请求代码。</li>
+ <li>第二个Activity指定的结果代码。如果操作成功,这是 {@link
+android.app.Activity#RESULT_OK};如果用户退出或操作出于某种原因失败,则是 {@link
+android.app.Activity#RESULT_CANCELED}。
+</li>
+ <li>传送结果数据的 {@link android.content.Intent}。</li>
+</ul>
+
+<p>本例说明您可以如何处理“选择联系人”意向的结果。</p>
+
+<pre>
+&#64;Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // Check which request we're responding to
+ if (requestCode == PICK_CONTACT_REQUEST) {
+ // Make sure the request was successful
+ if (resultCode == RESULT_OK) {
+ // The user picked a contact.
+ // The Intent's data Uri identifies which contact was selected.
+
+ // Do something with the contact here (bigger example below)
+ }
+ }
+}
+</pre>
+
+<p>在本例中, Android 的“联系人”应用返回的结果 {@link android.content.Intent} 提供识别用户所选联系人的内容 {@link android.net.Uri}。
+
+</p>
+
+<p>为了成功处理结果,您必须了解结果的
+{@link android.content.Intent} 的格式。当返回结果的Activity是您自己的Activity之一时,这便非常容易。
+Andriod 平台附带的应用提供它们自己的 API,您可用这些 API 获取特定结果数据。
+例如,“联系人” 应用(在一些较旧的版本中是 Contacts 应用)始终返回带内容 URI(识别所选联系人)的结果,并且“照相机” 应用在 {@code "data"} 额外项中返回 {@link android.graphics.Bitmap}(请参阅有关
+<a href="{@docRoot}training/camera/index.html">拍摄照片</a>的课程)。
+
+</p>
+
+
+<h4>奖励:接收联系人数据</h4>
+
+<p>显示如何从“联系人”应用获取结果的代码不会详细说明如何实际从结果读取数据,但它需要对<a href="{@docRoot}guide/topics/providers/content-providers.html">内容提供商</a>进行更深入的探讨。
+
+
+但是,如果您很好奇,此处提供了更多的代码向您展示如何查询结果数据,从所选联系人获取电话号码:
+</p>
+
+<pre>
+&#64;Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // Check which request it is that we're responding to
+ if (requestCode == PICK_CONTACT_REQUEST) {
+ // Make sure the request was successful
+ if (resultCode == RESULT_OK) {
+ // Get the URI that points to the selected contact
+ Uri contactUri = data.getData();
+ // We only need the NUMBER column, because there will be only one row in the result
+ String[] projection = {Phone.NUMBER};
+
+ // Perform the query on the contact to get the NUMBER column
+ // We don't need a selection or sort order (there's only one result for the given URI)
+ // CAUTION: The query() method should be called from a separate thread to avoid blocking
+ // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
+ // Consider using {@link android.content.CursorLoader} to perform the query.
+ Cursor cursor = getContentResolver()
+ .query(contactUri, projection, null, null, null);
+ cursor.moveToFirst();
+
+ // Retrieve the phone number from the NUMBER column
+ int column = cursor.getColumnIndex(Phone.NUMBER);
+ String number = cursor.getString(column);
+
+ // Do something with the phone number...
+ }
+ }
+}
+</pre>
+
+<p class="note"><strong>注意:</strong>在 Android 2.3(API 级别 9)之前, 在 {@link android.provider.ContactsContract.Contacts Contacts Provider} 上执行查询(如以上所示)需要您的应用声明 {@link
+android.Manifest.permission#READ_CONTACTS} 权限(请参阅<a href="{@docRoot}guide/topics/security/security.html">安全与权限</a>)。
+
+但是,自 Android 2.3 版本开始,“联系人”应用授予您的应用在联系人提供商向您返回结果时从联系人提供商临时读取信息的权限。
+
+该临时权限仅适用于所请求的特定联系人,因此您只能查询意向的 {@link android.net.Uri} 指定的联系人,除非您声明 {@link
+android.Manifest.permission#READ_CONTACTS} 权限。
+
+</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/zh-cn/training/basics/intents/sending.jd b/docs/html-intl/intl/zh-cn/training/basics/intents/sending.jd
new file mode 100644
index 0000000..f5b9c47
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/training/basics/intents/sending.jd
@@ -0,0 +1,256 @@
+page.title=向另一个应用发送用户
+page.tags=意向
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>本课程将向您展示如何</h2>
+<ol>
+ <li><a href="#Build">构建隐含意向</a></li>
+ <li><a href="#Verify">确认是否存在接收意向的应用</a></li>
+ <li><a href="#StartActivity">开始具有意向的Activity</a></li>
+ <li><a href="#AppChooser">显示应用选择器</a></li>
+</ol>
+
+<h2>您还应阅读</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">共享简单数据</a></li>
+</ul>
+
+ </div>
+</div>
+
+<p>Android 最重要的功能之一是应用能够基于它要执行的“操作”向另一个应用发送用户。
+例如,如果您的应用有您要在地图上显示的公司地址,您无需在显示地图的应用中构建Activity。
+
+而是可以创建使用
+ {@link android.content.Intent} 查看地址的请求。Android 系统之后启动可以在地图上显示该地址的应用。
+</p>
+
+<p>正如第一堂课<a href="{@docRoot}training/basics/firstapp/index.html">构建您的第一个应用</a>中所讲述的,您必须使用意向在自己应用中的Activity之间进行导航。您通常使用<em>明确意向</em>执行此操作,该意向定义您希望启动的组件的确切类名称。
+
+
+但是,当您希望另一应用执行操作时,比如“查看地图”,您必须使用<em>隐含意向</em>。
+</p>
+
+<p>本课程向您展示如何针对特定操作创建隐含意向,以及如何使用该意向开始在另一个应用中执行操作的Activity。
+</p>
+
+
+
+<h2 id="Build">构建隐含意向</h2>
+
+<p>隐含意向不声明要启动的组件的类名称,而是声明要执行的操作。
+该操作指定您要执行的操作,比如<em>查看</em>、<em>编辑</em>、<em>发送</em>或 <em>获取</em> 某项。
+意向通常还包含与操作关联的数据,比如您要查看的地址或您要发送的电子邮件消息。根据要创建的意向,数据可能是 {@link android.net.Uri}、多种其他数据类型之一,或意向可能根本就不需要数据。
+
+
+</p>
+
+<p>如果您的数据是 {@link android.net.Uri},有一个简单的 {@link
+android.content.Intent#Intent(String,Uri) Intent()} 构造函数,您可用来定义操作和数据。
+</p>
+
+<p>例如,此处显示如何使用指定电话号码的 {@link
+android.net.Uri} 数据创建发起电话呼叫的意向:</p>
+
+<pre>
+Uri number = Uri.parse("tel:5551234");
+Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
+</pre>
+
+<p>当您的应用通过调用 {@link android.app.Activity#startActivity
+startActivity()} 调用此意向时,“电话”应用会发起向指定电话号码的呼叫。</p>
+
+<p>这里有一些其他意向及其操作和 {@link android.net.Uri} 数据对:
+</p>
+
+<ul>
+ <li>查看地图:
+<pre>
+// Map point based on address
+Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
+// Or map point based on latitude/longitude
+// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
+Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
+</pre>
+ </li>
+ <li>查看网页:
+<pre>
+Uri webpage = Uri.parse("http://www.android.com");
+Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
+</pre>
+ </li>
+</ul>
+
+<p>其他类型的隐含意向需要提供不同数据类型(比如,字符串)的“额外”数据。
+您可以使用各种 {@link
+android.content.Intent#putExtra(String,String) putExtra()} 方法添加一条或多条额外数据。</p>
+
+<p>默认情况下,系统基于所包含的
+{@link android.net.Uri} 数据确定意向需要的相应 MIME 类型。如果您未在意向中包含 {@link android.net.Uri},您通常应使用 {@link android.content.Intent#setType setType()} 指定与意向关联的数据的类型。
+
+设置 MIME 类型可进一步指定哪些类型的Activity应接收意向。
+</p>
+
+<p>此处有更多添加额外数据以指定所需操作的意向:</p>
+
+<ul>
+ <li>发送带附件的电子邮件:
+<pre>
+Intent emailIntent = new Intent(Intent.ACTION_SEND);
+// The intent does not have a URI, so declare the "text/plain" MIME type
+emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
+emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients
+emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
+emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
+emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));
+// You can also attach multiple items by passing an ArrayList of Uris
+</pre>
+ </li>
+ <li>创建日历事件:
+<pre>
+Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
+Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);
+Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);
+calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
+calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
+calendarIntent.putExtra(Events.TITLE, "Ninja class");
+calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");
+</pre>
+<p class="note"><strong>注意:</strong>只有 API 级别 14 或更高级别支持此日历事件意向。
+</p>
+ </li>
+</ul>
+
+<p class="note"><strong>注意:</strong>尽可能具体地定义您的 {@link
+android.content.Intent} 非常重要。例如,如果您想要使用 {@link android.content.Intent#ACTION_VIEW} 意向显示图像,您应指定
+{@code image/*}的 MIME 类型。
+这可防止可“查看”数据的其他类型的应用(比如地图应用)被意向触发。
+</p>
+
+
+
+<h2 id="Verify">确认是否存在接收意向的应用</h2>
+
+<p>尽管 Android 平台保证某些意向可以分解为内置应用之一(比如,“电话”、“电子邮件”或“日历”应用),您应在调用意向之前始终包含确认步骤。
+
+</p>
+
+<p class="caution"><strong>注意:</strong>如果您调用了意向,但设备上没有可用于处理意向的应用,您的应用将崩溃。
+</p>
+
+<p>要确认是否存在可响应意向的可用Activity,请调用 {@link
+android.content.pm.PackageManager#queryIntentActivities queryIntentActivities()} 来获取能够处理您的{@link android.content.Intent} 的Activity列表。
+如果返回的 {@link
+java.util.List} 不为空,您可以安全地使用该意向。例如:</p>
+
+<pre>
+PackageManager packageManager = {@link android.content.Context#getPackageManager()};
+List<ResolveInfo> activities = packageManager.queryIntentActivities(intent,
+ PackageManager.MATCH_DEFAULT_ONLY);
+boolean isIntentSafe = activities.size() > 0;
+</pre>
+
+<p>如果 <code>isIntentSafe</code> 是 <code>true</code>,则至少有一个应用将响应该意向。
+如果它是 <code>false</code>,则没有任何应用处理该意向。</p>
+
+<p class="note"><strong>注意:</strong>在您需要在用户尝试使用它之前禁用使用该意向的功能时,您应在Activity初次开始时执行此检查。
+
+如果您了解可处理意向的特定应用,您还可以为用户提供下载该应用的链接(请参阅如何<a href="{@docRoot}distribute/tools/promote/linking.html">在 Google
+Play</a> 链接到您的产品)。
+</p>
+
+
+<h2 id="StartActivity">开始具有意向的Activity</h2>
+
+<div class="figure" style="width:200px;margin-top:-10px">
+ <img src="{@docRoot}images/training/basics/intents-choice.png" alt="" />
+ <p class="img-caption"><strong>图 1.</strong>当多个应用可处理意向时显示的选择对话框示例。
+</p>
+</div>
+
+<p>一旦您已创建您的 {@link android.content.Intent} 并设置附加信息,调用 {@link
+android.app.Activity#startActivity startActivity()} 将其发送给系统 。如果系统识别可处理意向的多个Activity,它会为用户显示对话框供其选择要使用的应用,如图 1 所示。
+
+如果只有一个Activity处理意向,系统会立即开始这个Activity。
+</p>
+
+<pre>
+startActivity(intent);
+</pre>
+
+<p>此处显示完整的示例:如何创建查看地图的意向,确认是否存在处理意向的应用,然后启动它:
+</p>
+
+<pre>
+// Build the intent
+Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
+Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
+
+// Verify it resolves
+PackageManager packageManager = {@link android.content.Context#getPackageManager()};
+List&lt;ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
+boolean isIntentSafe = activities.size() > 0;
+
+// Start an activity if it's safe
+if (isIntentSafe) {
+ startActivity(mapIntent);
+}
+</pre>
+
+
+
+<h2 id="AppChooser">显示应用选择器</h2>
+
+<div class="figure" style="width:200px;margin-top:-10px">
+ <img src="{@docRoot}images/training/basics/intent-chooser.png" alt="" />
+ <p class="img-caption"><strong>图 2.</strong>选择器的对话框。</p>
+</div>
+
+<p>注意,当您通过将您的 {@link android.content.Intent} 传递至 {@link
+android.app.Activity#startActivity startActivity()} 而开始Activity时,有多个应用响应意向,用户可以选择默认使用哪个应用(通过选中对话框底部的复选框;见图 1)。
+
+当执行用户通常希望每次使用相同应用进行的操作时,比如当打开网页(用户可能只使用一个网页浏览器)或拍照(用户可能习惯使用一个照相机)时,这非常有用。
+
+</p>
+
+<p>但是,如果要执行的操作可由多个应用处理并且用户可能习惯于每次选择不同的应用,&mdash;比如“共享”操作,用户有多个应用分享项目&mdash;,您应明确显示选择器对话框,如图 2 所示。
+
+
+选择器对话框强制用户选择用于每次操作的应用(用户不能对此操作选择默认的应用)。
+
+</p>
+
+<p>要显示选择器,使用 {@link
+android.content.Intent#createChooser createChooser()} 创建{@link android.content.Intent} 并将其传递至 {@link
+android.app.Activity#startActivity startActivity()}。例如:</p>
+
+<pre>
+Intent intent = 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 chooser
+Intent chooser = Intent.createChooser(intent, title);
+
+// Verify the intent will resolve to at least one activity
+if (intent.resolveActivity(getPackageManager()) != null) {
+ startActivity(chooser);
+}
+</pre>
+
+<p>这将显示一个对话框,其中有响应传递给 {@link
+android.content.Intent#createChooser createChooser()} 方法的意向的应用列表,并且将提供的文本用作
+对话框标题。</p>
+
+
+
diff --git a/docs/html-intl/intl/zh-tw/design/get-started/principles.jd b/docs/html-intl/intl/zh-tw/design/get-started/principles.jd
new file mode 100644
index 0000000..27cce81
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/design/get-started/principles.jd
@@ -0,0 +1,307 @@
+page.title=Android 設計原則
+@jd:body
+
+<p>這些設計原則是由 Android 使用者體驗團隊開發,並針對 Android 使用者體驗團隊的需求所開發,以使用者的最大利益為出發點。對於 Android 開發者和設計者而言,針對不同類型的裝置,這些原則仍持續是更詳細設計方針的基礎。
+
+
+
+</p>
+
+<p>
+當您套用您本身的創意與設計思維時,請考慮這些原則。
+偏離一般做法要帶有目的。
+</p>
+
+<h2 id="enchant-me">使人著迷</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="delight-me">以出乎意外的方式取悅人</h4>
+<p>漂亮的外觀、精心設置的動畫,或時機恰到好處的音效,都是令人感到喜悅的體驗。
+微妙的效果有助於產生毫不費力及強大力量就在手邊的感覺。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_delight.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="real-objects-more-fun">真實的物件比按鈕和功能表更有趣</h4>
+<p>讓人們可以在您應用程式中直接輕觸和操縱物件,這可減少執行某項工作所需的認知過程,同時在情緒上更令人感到滿足。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_real_objects.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="make-it-mine">提供個人設定</h4>
+<p>人們喜歡加上個人風格,因為這有助於他們感到自在並握有主控權。提供能令人感受及美觀的預設設定,但也可以考慮使用不會阻礙主要工作卻又好玩的可選用性自訂項目。
+
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_make_it_mine.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="get-to-know-me">設法了解使用者</h4>
+<p>隨著時間而學習使用者的偏好。讓人們易於取得之前的選擇,而不是一再詢問他們會做出相同選擇的問題。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_get_to_know_me.png">
+
+ </div>
+</div>
+
+<h2 id="simplify-my-life">簡化生活</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="keep-it-brief">保持簡潔</h4>
+<p>以簡單單字組成簡短語句。人們傾向於略過冗長的句子。</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_keep_it_brief.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="pictures-faster-than-words">圖片的傳達效果更勝於言語</h4>
+<p>請考慮使用圖片來解釋想法。圖片能吸引人們的注意力,並比言語更有效率。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_pictures.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="decide-for-me">幫使用者決定,但使用者擁有最終決定權</h4>
+<p>做出最好的猜測,先行動,而非先詢問。太多的選擇和決定會讓人們不高興。
+為防止錯誤,務必允許復原。</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_decide_for_me.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="only-show-when-i-need-it">必要時僅顯示使用者需要的東西</h4>
+<p>人們無法承受一次看到太多東西。將工作和資訊細分成小型、易消化的區塊。
+隱藏當下不重要的選項,但在人們需要選擇時要明確指導。</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_information_when_need_it.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="always-know-where-i-am">使用者應該總是清楚所在位置</h4>
+<p>給人們信心,知道自己沒有迷路。讓您應用程式中的各處看起來都有獨特性,並使用轉換來顯示畫面之間的關係。
+針對進行中的工作提供回饋。</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_navigation.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="never-lose-my-stuff">別弄丟使用者的東西</h4>
+<p>儲存使用者花時間所建立的資訊,並且讓使用者可從任何地方存取。跨手機、平板電腦和電腦記住設定、個人風格和建立的資訊。
+這會讓升級變得很簡單。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_never_lose_stuff.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="looks-same-should-act-same">如果看起來一樣,就應該有相同的動作</h4>
+<p>讓功能看起來就不一樣,而非變化微妙,這可以協助人們辨別功能差異。在相同輸入環境下,因為模式看起來很類似但卻有不同的動作,請盡量避免使用。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_looks_same.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="interrupt-only-if-important">重要時才打斷</h4>
+<p>就像一位好的私人助理,讓人們免於無關緊要的枝微末節。人們總想集中注意力,除非很重要且具時效性,不然貿然中斷會令人感到費力且沮喪。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_important_interruption.png">
+
+ </div>
+</div>
+
+<h2 id="make-me-amazing">讓使用者驚艷</h2>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="give-me-tricks">提供使用者各處通用的訣竅</h4>
+<p>當人們能自行弄清楚來龍去脈時是很棒的體驗。運用來自其他 Android 應用程式的視覺模式和肌肉記憶效應,讓使用者更易於學會您的應用程式。
+例如,擺動手勢可能是很好的導覽捷徑。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_tricks.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="its-not-my-fault">不是使用者的錯</h4>
+<p>提示人們更正時要溫和。人們使用您的應用程式時,會想要感受到自已非常明智。如果有什麼不對,請提供明確的復原指示,但不需要使用者明瞭技術細節。如果可以,請盡量在幕後修正。
+
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_error.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="sprinkle-encouragement">分段鼓勵</h4>
+<p>將複雜工作細分成更小的步驟,讓使用者可以輕鬆完成。對動作給予回饋,即使只是個微光效果。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_sprinkle_encouragement.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="do-heavy-lifting-for-me">為使用者處理繁重的工作</h4>
+<p>讓新手也能做出以前從未想像過可以辦到的事情,讓使用者有專家的感覺。例如,組合多個相片效果的捷徑,只要幾個步驟,即可讓業餘照片令人驚艷。
+
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_heavy_lifting.png">
+
+ </div>
+</div>
+
+<div class="vspace size-2">&nbsp;</div>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-7">
+
+<h4 id="make-important-things-fast">快速找到重要的功能</h4>
+<p>並非所有的動作都一視同仁。決定應用程式中最重要的部分,並讓使用者易於找到並可迅速使用,例如相機的快門按鈕或音樂播放器的暫停按鈕。
+</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+
+ <img src="{@docRoot}design/media/principles_make_important_fast.png">
+
+ </div>
+</div>
diff --git a/docs/html-intl/intl/zh-tw/design/material/index.jd b/docs/html-intl/intl/zh-tw/design/material/index.jd
new file mode 100644
index 0000000..620ee6e
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/design/material/index.jd
@@ -0,0 +1,186 @@
+page.title=材料設計
+page.tags=Material, design
+page.type=設計
+page.image=design/material/images/MaterialLight.png
+
+@jd:body
+
+<!-- developer docs box -->
+<a class="notice-developers right" href="{@docRoot}training/material/index.html">
+ <div>
+ <h3>開發人員文件</h3>
+ <p>使用材料設計建立應用程式</p>
+ </div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw">
+<div>
+ <h3>影片</h3>
+ <p>材料設計簡介</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw">
+<div>
+ <h3>影片</h3>
+ <p>紙張和墨水:重要的材料</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc">
+<div>
+ <h3>影片</h3>
+ <p>Google I/O 應用程式中的材料設計</p>
+</div>
+</a>
+
+
+
+<p itemprop="description">材料設計是一份內容廣泛的綜合性指南,引導您跨平台、跨裝置進行視覺、動態和互動的設計。
+Android 現已納入對材料設計應用程式的支援。
+如果要在 Android 應用程式中使用材料設計,請依照<a href="http://www.google.com/design/spec">材料設計規格</a>中定義的指示,並使用
+Android
+5.0 (API 層級 21) 或後續版本中的新元件和新功能。</p>
+
+<p>Android 提供下列元素,供您打造材料設計應用程式:</p>
+
+<ul>
+ <li>一個新的設計風格</li>
+ <li>用於複雜檢視的小工具</li>
+ <li>自訂陰影和動畫的新 API</li>
+</ul>
+
+<p>如需取得如何在 Android 上實作材料設計的詳細資訊,請詳見<a href="{@docRoot}training/material/index.html">使用材料設計建立應用程式</a>。
+</p>
+
+
+<h3>材料設計風格</h3>
+
+<p>材料設計風格提供您應用程式使用的新樣式、可以讓您設定色板的系統小工具,並針對輕觸回饋與操作行為轉換提供預設動畫。
+</p>
+
+<!-- two columns -->
+<div style="width:700px;margin-top:25px;margin-bottom:20px">
+<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>
+ </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>
+ </div>
+</div>
+<br style="clear:left"/>
+</div>
+
+<p>如需詳細資訊,請參閱<a href="{@docRoot}training/material/theme.html">使用材料設計風格</a>。
+</p>
+
+
+<h3>清單和卡片</h3>
+
+<p>Android 提供兩個新的小工具,搭配材料設計樣式與動畫,可用來顯示清單和卡片:
+</p>
+
+<!-- two columns -->
+<div style="width:700px;margin-top:25px;margin-bottom:20px">
+<div style="float:left;width:250px;margin-left:40px;margin-right:60px;">
+ <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" />
+ <p>新的 <code>RecyclerView</code> 小工具是 <code>ListView</code>
+更容易插入的版本,支援不同的版面配置類型,並提供效能改善。</p>
+</div>
+<div style="float:left;width:250px;margin-right:0px;">
+ <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" />
+ <p>新的 <code>CardView</code> 小工具讓您可以顯示卡片內的重要資訊,並且該資訊都能擁有一致的外觀與風格。
+</p>
+</div>
+<br style="clear:left"/>
+</div>
+
+<p>如需詳細資訊,請參閱<a href="{@docRoot}training/material/lists-cards.html">建立清單和卡片</a>。
+</p>
+
+
+<h3>檢視陰影</h3>
+
+<p>除了 X 和 Y 屬性外,Android 中的檢視現在也有 Z 屬性。
+這個新屬性代表檢視的高度,這會決定:</p>
+
+<ul>
+<li>陰影大小:帶有較高 Z 值的檢視會投射更大的陰影。</li>
+<li>繪製順序:具有較高 Z 值的檢視會顯示在其他檢視之上。</li>
+</ul>
+
+<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/videos/ContactsAnim.webm"/>
+ <source src="{@docRoot}design/videos/ContactsAnim.ogv"/>
+ </video>
+ </div>
+ <div style="font-size:10pt;margin-left:20px;margin-bottom:30px">
+ 如要重播影片,請按一下裝置螢幕<em></em>
+ </div>
+</div>
+
+<p>如需取得詳細資訊,請參閱<a href="{@docRoot}training/material/shadows-clipping.html">定義陰影和裁剪檢視</a>。
+</p>
+
+
+<h3>動畫</h3>
+
+<p>新的動畫 API 可針對 UI 控制項的輕觸回饋、檢視狀態中的變更,以及行為轉換,讓您建立自訂動畫。
+</p>
+
+<p>這些 API 讓您可以:</p>
+
+<ul>
+<li style="margin-bottom:15px">
+回應您檢視中有<strong>輕觸回饋</strong>動畫的輕觸事件。
+</li>
+<li style="margin-bottom:15px">
+隱藏和顯示有<strong>循環顯示</strong>動畫的檢視。
+</li>
+<li style="margin-bottom:15px">
+在有自訂<strong>行為轉換</strong>動畫的行為間切換。
+</li>
+<li style="margin-bottom:15px">
+使用<strong>曲線動作</strong>建立更自然的動畫。
+</li>
+<li style="margin-bottom:15px">
+在帶有<strong>檢視狀態變更</strong>動畫的一個或多個檢視屬性中變更動畫。
+</li>
+<li style="margin-bottom:15px">
+在檢視狀態變更間,顯示<strong>狀態清單可繪項目</strong>中的動畫。
+</li>
+</ul>
+
+<p>輕觸回饋動畫會內建於數個標準檢視中,例如按鈕等。新 API 可讓您自訂這些動畫,並將其新增至您的自訂檢視中。
+</p>
+
+<p>如需詳細資訊,請參閱<a href="{@docRoot}training/material/animations.html">定義自訂動畫</a>。
+</p>
+
+
+<h3>可繪項目</h3>
+
+<p>可繪項目的這些新功能可以幫助您實作材料設計應用程式:</p>
+
+<ul>
+<li><strong>矢量可繪項目</strong>可以調整大小,但又不會喪失定義,最適合於應用程式中的單色圖示。
+</li>
+<li><strong>可繪項目著色</strong>可讓您在執行階段將點陣圖定義為 Alpha 遮罩,並以一個顏色進行著色。
+</li>
+<li><strong>顏色提取</strong>可讓您自動從點陣圖影像中提取顯著顏色。
+</li>
+</ul>
+
+<p>如需詳細資訊,請參閱<a href="{@docRoot}training/material/drawables.html">使用可繪項目</a>。
+</p>
diff --git a/docs/html-intl/intl/zh-tw/design/patterns/confirming-acknowledging.jd b/docs/html-intl/intl/zh-tw/design/patterns/confirming-acknowledging.jd
new file mode 100644
index 0000000..ac8975f
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/design/patterns/confirming-acknowledging.jd
@@ -0,0 +1,70 @@
+page.title=確認及確認完成
+page.tags=dialog,toast,notification
+@jd:body
+
+<p>在某些情況下,當使用者在您應用程式中呼叫一個動作時,最好是透過文字來「確認」(confirm) <em></em>或「確認完成」<em></em>(acknowledge)。</p>
+
+<div class="layout-content-row">
+ <div class="layout-content-col span-6">
+ <img src="{@docRoot}design/media/confirm_ack_confirming.png">
+ <p><strong>確認</strong>是要求使用者確認真的要進行剛剛呼叫的動作。在某些情況下,確認訊息出現時會伴隨警告或需要使用者考量是否採取動作的相關重要資訊。</p>
+ </div>
+ <div class="layout-content-col span-6">
+ <img src="{@docRoot}design/media/confirm_ack_acknowledge.png">
+ <p><strong>確認完成</strong>是顯示文字,讓使用者知道已經完成剛剛呼叫的動作。這會排除系統正在採取之隱式作業的不確定性。在某些情況下,確認完成出現時會伴隨復原動作的選項。</p>
+ </div>
+</div>
+
+<p>使用這種方式和使用者溝通有助於降低已發生或將發生事情的不確定性。確認或確認完成也可以防止使用者誤犯可能會後悔的錯誤。</p>
+
+<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">
+ <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">
+ <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">
+ <h4>範例:已儲存放棄的 Gmail 草稿</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_draftsave.png">
+ <p>在此範例中,如果使用者從 Gmail 撰寫畫面返回,可能會發生預期外的狀況:會自動儲存目前的草稿。以快顯通知 (toast) 形式出現的確認完成,會讓使用者明瞭此情況。確認完成會在幾秒鐘後淡出。</p>
+ <p>在此並不合適使用復原功能,因為儲存動作是由應用程式發起,而非使用者。瀏覽至草稿清單,就可以方便且快速地繼續撰寫。</p>
+
+ </div>
+ <div class="layout-content-col span-6">
+ <h4>範例:已刪除 Gmail 會話群組</h4>
+ <img src="{@docRoot}design/media/confirm_ack_draft_deleted.png">
+ <p>使用者從 Gmail 清單中刪除一個會話群組後,會出現確認完成訊息,並提供一個復原選項。確認完成會持續出現,直到使用者採取不相關的動作,例如捲動清單。</p>
+ </div>
+</div>
+
+<h2>無「確認」或「確認完成」</h2>
+<div class="layout-content-row">
+ <div class="layout-content-col span-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">
+ <h4>範例:從主螢幕移除應用程式</h4>
+ <img src="{@docRoot}design/media/confirm_ack_ex_removeapp.png">
+ <p><strong>確認並非必要</strong>。這是特意設計的動作:使用者必須拖曳項目放到相對較大且隔離的目標上。因此極不可能發生意外狀況。但如果使用者後悔所做的決定,只需幾秒鐘,就可以恢復原狀。</p>
+ <p><strong>確認完成並非必要</strong>。使用者會知道應用程式從主螢幕消失,因為是他們將應用程式拖曳離開,所以才會消失。</p>
+
+ </div>
+</div>
diff --git a/docs/html-intl/intl/zh-tw/design/patterns/navigation.jd b/docs/html-intl/intl/zh-tw/design/patterns/navigation.jd
new file mode 100644
index 0000000..db160c2
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/design/patterns/navigation.jd
@@ -0,0 +1,213 @@
+page.title=使用 [返回] 及 [上一層] 導覽
+page.tags="navigation","activity","task","up navigation","back navigation"
+page.image=/design/media/navigation_between_siblings_gmail.png
+@jd:body
+
+<a class="notice-developers" href="{@docRoot}training/implementing-navigation/index.html">
+ <div>
+ <h3>開發人員文件</h3>
+ <p>實作有效的導覽</p>
+ </div>
+</a>
+
+<p itemprop="description">一致的導覽是整體使用者體驗的必備組成。基本導覽的行為若不一致又令人意外,是最令使用者感到更沮喪的狀況。
+Android 3.0 已將重大變更導入全域的導覽行為中。
+完全遵循 [返回] 及 [上一層] 的方針,會讓使用者感到您的應用程式導覽既可靠又符合預期。
+</p>
+<p>Android 2.3 和更早版本依賴系統 [返回]
+<em></em>按鈕,以支援應用程式內的導覽。在 Android 3.0 導入動作列之後,出現第二個導覽機制:[上一層]
+<em></em>按鈕,由應用程式圖示和左指符號組成。</p>
+
+<img src="{@docRoot}design/media/navigation_with_back_and_up.png">
+
+<h2 id="up-vs-back">[上一層] vs.[返回]</h2>
+
+<p>[上一層] 按鈕用於在畫面間有階層關係的應用程式中導覽。
+例如,如果畫面 A
+顯示項目清單,然後選擇其中一個項目導致進入畫面 B (更詳細呈現該項目),那麼畫面 B 應該提供 [上一層] 按鈕,以便返回畫面 A。
+</p>
+<p>如果畫面是在應用程式中的最頂端 (亦即應用程式的首頁),則不應該會有 [上一層]按鈕。
+</p>
+
+<p>系統 [返回] 按鈕用於逆時間順序導覽,透過歷程記錄,可以經歷使用者最近使用過的畫面。
+[返回] 通常基於畫面之間的暫時關係,而非應用程式的階層。
+</p>
+
+<p>當先前檢視的畫面也是目前畫面的階層父項時,按下
+[返回] 按鈕和按下 [上一層] 按鈕效果相同 &mdash; 這是常見的狀況。
+然而,與 [上一層] 按鈕不同的是 (該按鈕可以確保使用者仍停留在您的應用程式內):[返回]
+按鈕可以讓使用者返回主畫面,或甚至是不同的應用程式。</p>
+
+<img src="{@docRoot}design/media/navigation_up_vs_back_gmail.png">
+
+<p>[返回] 按鈕還支援幾個間接關聯畫面對畫面導覽的行為:
+</p>
+<ul>
+<li>關閉浮動視窗 (對話、快顯)</li>
+<li>關閉內容相關的動作列,並從選取項目移除醒目顯示</li>
+<li>隱藏畫面鍵盤 (IME)</li>
+</ul>
+<h2 id="within-app">在應用程式內導覽</h2>
+
+<h4>導覽至具有多重入口的畫面</h4>
+<p>有時候,一個畫面在應用程式的階層中並沒有嚴謹的位置,而且可以從多個入口存取 &mdash; 例如可以從您應用程式中任何其他畫面存取的設定畫面。在這種情況下,[上一層]
+按鈕應該選擇返回導引至此畫面的前一畫面,這個行為與 [返回] 相同。
+
+</p>
+<h4>在畫面內變更檢視</h4>
+<p>變更畫面的檢視選項並不會變更 [上一層] 或 [返回] 的行為:畫面仍維持在應用程式階層中的相同位置,並不會建立新的導覽歷程記錄。
+</p>
+<p>這類檢視變更的範例如下:</p>
+<ul>
+<li>使用標籤和/或左與右滑動來切換檢視</li>
+<li>使用下拉清單 (亦即折疊標籤) 切換檢視</li>
+<li>篩選清單</li>
+<li>對清單排序</li>
+<li>變更顯示特性 (如縮放)</li>
+</ul>
+<h4>在同層級畫面間導覽</h4>
+<p>當您的應用程式支援從項目清單導覽至項目之一的詳細檢視時,使用者通常會想使用方向導覽功能,以便從該項目導覽至清單中的前一個或後一個項目。
+
+例如在 Gmail 中,可以很容易從會話群組向左或右滑動,方便檢視相同「收件匣」中的較新或舊會話群組。
+就像在一個畫面中變更檢視時,這類導覽不會變更 [上一層] 或 [返回] 的行為。
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_gmail.png">
+
+<p>然而有一個明顯的例外是,在不被引用清單綁在一起的相關詳細資料檢視之間瀏覽時 &mdash; 例如在 Play 商店中於相同開發者的不同應用程式之間瀏覽時,或是在相同演出者的專輯間瀏覽時。
+
+在這些情況下,瀏覽每個連結都會產生歷程記錄,這會造成 [返回] 按鈕會經歷每個先前檢視過的畫面。
+[上一層] 應該會繼續略過這些相關的畫面,並導覽到最近檢視過的容器畫面。
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_market1.png">
+
+<p>基於您對詳細資料檢視的瞭解,您有能力讓 [上一層] 行為甚至變得更聰明。
+再延伸說明之前提及的 Play 商店範例,想像使用者已從最近檢視的「書籍」導覽至「電影」改編的詳細資料。
+在這種情況下,[上一層]
+可以返回到使用者之前沒有導覽過的上層容器 (電影)。</p>
+
+<img src="{@docRoot}design/media/navigation_between_siblings_market2.png">
+
+<h2 id="into-your-app">透過「主畫面小工具」和「通知」,導覽至您的應用程式</h2>
+
+<p>您可以使用主畫面小工具或通知,協助您直接導覽至深入您應用程式階層中的畫面。
+例如,Gmail 的「收件匣」小工具和新郵件通知,都可以略過「收件匣」畫面,將使用者直接帶到會話群組檢視之中。
+</p>
+
+<p>針對這兩種情況,可以使用下列方式來處理 [上一層] 按鈕:</p>
+
+<ul>
+<li>如果目的地畫面通常是透過您應用程式中的一個特定畫面到達,那麼 [上一層] 應該要導覽至該畫面。<em></em>
+</li>
+<li>否則<em></em>, [上一層] 應該導覽至您應用程式的最頂端 (「主」) 畫面。</li>
+</ul>
+
+<p>就 [返回] 按鈕而言,您應讓導覽更符合預期,方法是在工作的返回堆疊中,插入前往應用程式最頂端畫面的完整向上導覽路徑。
+這可讓忘了如何進入您應用程式的使用者,能在退出之前導覽至應用程式的最頂端畫面。
+
+</p>
+
+<p>舉例來說,Gmail 的主畫面小工具有一個按鈕,可以直接往下進入撰寫畫面。
+來自撰寫畫面的 [上一層] 或 [返回] 按鈕,會將使用者帶到「收件匣」中,而此處的 [返回] 按鈕則可繼續前往至「主畫面」。
+</p>
+
+<img src="{@docRoot}design/media/navigation_from_outside_back.png">
+
+<h4>間接通知</h4>
+
+<p>當您的應用程式需要同時呈現多個事件的資訊時,可以使用單一通知,引導使用者進入一個插頁畫面。
+此畫面會摘要這些事件,並提供路徑,讓使用者可以深入應用程式之中。這種風格的通知稱為「間接通知」<em></em>。
+
+</p>
+
+<p>與標準 (直接) 通知不同的是,從間接通知的插頁畫面按下 [返回],會讓使用者返回至通知觸發的起點 &mdash; 無其他畫面會插入至返回堆疊之中。
+
+一旦使用者從插頁畫面繼續進入應用程式之後,[上一層]
+與 [返回] 會如上所述,其行為就像針對標準通知一樣:在應用程式內導覽,而非返回插頁畫面。
+</p>
+
+<p>例如,假設 Gmail 中的使用者收到來自「行事曆」的間接通知。輕觸這個通知會打開插頁畫面,而此畫面會顯示數個不同事件的提醒。
+
+從插頁畫面輕觸 [返回],會讓使用者返回至 Gmail。輕觸特定事件會將使用者帶離插頁畫面,並進入完整的「行事曆」應用程式,顯示事件的詳細資料。
+
+從事件詳細資料中,[上一層] 和 [返回] 會導覽至「行事曆」的最頂層檢視。</p>
+
+<img src="{@docRoot}design/media/navigation_indirect_notification.png">
+
+<h4>快顯通知</h4>
+
+<p>快顯通知<em></em>會略過通知匣,直接出現在使用者面前。
+這不常使用,<strong>應該要保留在需要適時回應,以及必須中斷使用者前後關聯動作的時候</strong>。
+例如,Talk
+就使用這種風格,用來提示使用者有朋友邀請加入視訊聊天,而且此邀請會在幾秒之後自動過期。
+</p>
+
+<p>就導覽行為而言,快顯通知緊接著間接通知插頁畫面的行為。
+[返回] 會關閉快顯通知。如果使用者從快顯導覽進入通知應用程式,[上一層]
+和 [返回] 會遵循標準通知的規則,只在應用程式內導覽。
+</p>
+
+<img src="{@docRoot}design/media/navigation_popup_notification.png">
+
+<h2 id="between-apps">在應用程式間導覽</h2>
+
+<p>Android 系統的基本優點之一是應用程式互相啟動的能力,讓使用者能夠直接從一個應用程式導覽至另一個應用程式。
+例如,需要擷取一張相片的應用程式可以啟動「相機」應用程式,而此應用程式會將相片傳回引用的應用程式。開發人員可以輕鬆利用其他應用程式的程式碼,而使用者在經常執行的動作中可以享受一致性的體驗,這對雙方都是一大好處。
+
+
+
+</p>
+
+<p>要瞭解應用程式對應用程式的導覽,重要的是要瞭解以下討論的 Android 架構行為。
+</p>
+
+<h4>活動、工作和意圖</h4>
+
+<p>在 Android 中,<strong>活動</strong>是一個應用程式元件,定義了資訊畫面,以及使用者可以執行的所有關聯動作。
+您的應用程式是個活動的集合,包括您可以建立及您能從其他應用程式重複使用的活動。
+</p>
+
+<p><strong>工作</strong>是使用者遵循以達到目標的一系列活動。單一工作可以利用來自單一應用程式的活動,或是汲取數個不同應用程式的活動。
+
+</p>
+
+<p><strong>意向</strong>是指應用程式所發出想要另一套應用程式協助執行某動作訊號的機制。
+應用程式的活動可指示其可回應哪些意向。
+針對如「共用」等常見意向,使用者可能已安裝許多可以滿足此要求的應用程式。
+</p>
+
+<h4>範例:在應用程式間導覽,以支援共用</h4>
+
+<p>要理解活動、工作和意向如何攜手合作,請思考應用程式如何讓使用者使用另一套應用程式來共用內容。例如,從「主」畫面啟動 Play 商店應用程式,開始新工作 A (見下圖)。
+
+在導覽經歷 Play 商店,並輕觸一本促銷的書籍以查看詳細資料後,使用者仍會停留在相同工作中,並透過新增行為延伸工作。
+觸發「共用」動作會提示使用者一個對話框,列出已註冊可用來處理「共用」意向的每個活動 (來自不同的應用程式)。
+
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_inward.png">
+
+<p>當使用者選擇透過 Gmail 共用,Gmail
+的撰寫活動會被新增為工作 A 的延續 &mdash; 而不會建立新工作。如果 Gmail 有本身的工作正在背景執行,這並不會影響該工作。
+</p>
+
+<p>從撰寫活動中,傳送訊息或輕觸 [返回] 按鈕,會讓使用者返回至書籍詳細資料的活動。
+繼續輕觸 [返回] 則會經由 Play 商店往回導覽,最終到達「主畫面」。
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_back.png">
+
+<p>然而,透過輕觸撰寫行為的 [上一層],代表使用者指明停留在 Gmail 的意願。
+Gmail 的會話群組清單活動會隨即出現,並針對該活動建立一個新的工作 B。新工作的最後根源都是「主畫面」,所以從會話群組輕觸 [返回] 會返回至該處。
+</p>
+
+<img src="{@docRoot}design/media/navigation_between_apps_up.png">
+
+<p>工作 A 仍然存在背景之中,而使用者可能會在稍後返回 (例如,透過「最近」畫面)。
+如果 Gmail 在背景正在執行自己的工作,則其會被工作 B 取代 &mdash; 並捨棄之前的前後關係,而就使用者的新目標。
+</p>
+
+<p>當您的應用程式註冊來處理具有深入應用程式階層活動的意向時,請參考<a href="#into-your-app">透過主畫面視窗小工具和通知,導覽至您的應用程式</a>,取得如何指定 [上一層] 導覽的指導方針。
+
+</p>
diff --git a/docs/html-intl/intl/zh-tw/design/patterns/notifications.jd b/docs/html-intl/intl/zh-tw/design/patterns/notifications.jd
new file mode 100644
index 0000000..3e3f59c
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/design/patterns/notifications.jd
@@ -0,0 +1,872 @@
+page.title=通知
+page.tags="notifications","design","L"
+@jd:body
+
+ <a class="notice-developers" href="{@docRoot}training/notify-user/index.html">
+ <div>
+ <h3>開發人員文件</h3>
+ <p>通知使用者</p>
+ </div>
+</a>
+
+<a class="notice-designers" href="notifications_k.html">
+ <div>
+ <h3>Android 4.4 及較早版本中的通知</h3>
+ </div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=Uiq2kZ2JHVY">
+<div>
+ <h3>影片</h3>
+ <p>DevBytes:Android L 開發者預覽版中的通知</p>
+</div>
+</a>
+
+<style>
+ .col-5, .col-6, .col-7 {
+ margin-left:0px;
+ }
+</style>
+
+<p>通知系統可以隨時知會使用者有關應用程式中的相關事件與及時事件,例如來自朋友的新聊天訊息。您可以將通知視為一種事件發生時警示使用者的新聞管道,或是在使用者沒注意時,記錄事件的日誌 &mdash; 並會視情況跨所有 Android 裝置且同步處理。
+
+
+
+
+
+</p>
+
+<h4 id="New"><strong>Android 5.0 新功能</strong></h4>
+
+<p>在 Android 5.0 中,通知會透過結構化、視覺化和功能化的效果接收重要更新:
+</p>
+
+<ul>
+ <li>通知已經有視覺方面的變更,與新的材料設計風格一致。
+</li>
+ <li> 現在可在裝置的鎖定螢幕上提供通知,而敏感內容仍可隱藏於其背後。
+
+</li>
+ <li>當裝置於使用中收到高優先順序的通知時,會使用稱為預告 (heads-up) 通知的新格式。
+</li>
+ <li>雲端同步化通知:關閉您其中一部 Android 裝置的通知,隨之也會在其他裝置上關閉此通知。
+
+</li>
+</ul>
+
+<p class="note"><strong>注意:</strong>此版本 Android 中的通知設計和先前版本大相徑庭。
+
+如需有關先前版本通知的設計資訊,請參閱
+<a href="./notifications_k.html">Android 4.4 及較早版本中的通知</a>。</p>
+
+<h2 id="Anatomy">通知的詳細分析</h2>
+
+<p>本節會重溫通知的基礎功能,以及其如何可在不同類型裝置上出現。
+</p>
+
+<h3 id="BaseLayout">基礎版面配置</h3>
+
+<p>至少,所有通知都必須包含一個基礎版面配置,它包含:</p>
+
+<ul>
+ <li> 通知的<strong>圖示</strong>。該圖示代表原始應用程式。如果應用程式會產生一種以上的通知類型,則圖示也有可能表示通知類型。
+
+
+</li>
+ <li> 一個通知<strong>標題</strong>和額外<strong>文字</strong>。
+</li>
+ <li> 一個<strong>時間戳記</strong>。</li>
+</ul>
+
+<p>針對先前平台版本,使用 {@link android.app.Notification.Builder Notification.Builder}
+所建立的通知其外觀與運作方式和在 Android 5.0
+中的一樣,只是在系統為您處理的方式上有一點樣式上的變更。
+如需更多有關 Android 先前版本通知的詳細資訊,請參閱
+<a href="./notifications_k.html">Android 4.4 及較早版本中的通知</a>。
+</p></p>
+
+
+ <img style="margin:20px 0 0 0" src="{@docRoot}images/android-5.0/notifications/basic_combo.png" alt="" width="700px" />
+
+
+<div style="clear:both;margin-top:20px">
+ <p class="img-caption">
+ 手持裝置通知的基礎版面配置 (左),以及穿戴裝置上的相同通知 (右),都帶有使用者相片及一個通知圖示
+
+ </p>
+ </div>
+
+<h3 id="ExpandedLayouts">擴充的版面配置</h3>
+
+
+<p>您可以選擇到底要讓您應用程式的通知提供多詳細的資料。
+通知可以顯示訊息的前幾行,也可以顯示較大的影像預覽。
+此額外資訊可提供使用者更多內容,而且 &mdash; 在某些情況下 &mdash; 可讓使用者讀取完整訊息。
+
+
+使用者可以捏合縮放或執行單手指滑動,在精簡的版面配置與擴充的版面配置間切換。
+
+
+ 對於單一事件通知,Android 提供三個擴充版面配置範本
+(文字、收件匣和影像),讓您可以在應用程式中使用。
+以下的影像顯示單一事件通知在手持裝置 (左) 和穿戴裝置 (右) 上的外觀。
+
+</p>
+
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/expandedtext_combo.png"
+ alt="" width="700px" height;="284px" />
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/stack_combo.png"
+ alt="" width="700px" height;="284px" />
+<img style="margin-top:30px"
+src="{@docRoot}images/android-5.0/notifications/ExpandedImage.png"
+ alt="" width="311px" height;="450px" />
+
+<h3 id="actions" style="clear:both; margin-top:40px">動作</h3>
+
+<p>Android 支援可以在通知底端顯示的選用動作。透過動作,使用者可針對特定通知,從通知欄 (notification shade) 內處理最常見的工作,而無需開啟原始啟動的應用程式。這可加速互動,而且在配合滑動關閉
+(swipe-to-dismiss)
+時,有助使用者專注於高重要性的通知。
+
+
+
+</p>
+
+
+ <img src="{@docRoot}images/android-5.0/notifications/action_combo.png" alt="" width="700px" />
+
+
+
+<p style="clear:both">明智地決定要在通知中要納入多少個動作。
+您納入的動作愈多,就會發現創造出愈複雜的通知。
+請納入最緊迫重要且有意義的動作,限制自己儘可能使用最少數目的動作。
+
+
+</p>
+
+<p>適合用於通知上的動作包含:</p>
+
+<ul>
+ <li> 必須是必要、頻繁且典型的想要顯示內容類型
+
+ <li> 可讓使用者快速完成工作
+</ul>
+
+<p>避免下列狀況:</p>
+
+<ul>
+ <li> 模稜兩可
+ <li> 和通知的預設動作相同 (如「讀取」或「開啟」)
+
+</ul>
+
+
+
+<p>您最多可以指定三個動作,每個動作都由一個動作圖示與名稱組成。
+
+ 為簡單的基礎版面配置新增動作,可讓通知變得更具擴充性
+--
+即使通知並未具備擴充的版面配置。由於動作只針對擴充的通知顯示,其他時候則隱藏,請確認使用者可從通知內呼叫的任何動作,也可以從關聯的應用程式中使用。
+
+
+
+
+</p>
+
+<h2 style="clear:left">預告通知</h2>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/hun-example.png" alt="" width="311px" />
+ <p class="img-caption">
+ 預告通知 (來電、高優先順序)
+出現在沉浸式應用程式之上的範例
+
+ </p>
+</div>
+
+<p>當高優先順序的通知到達 (如右) 時,會對使用者呈現很短的時間,且會顯示可能執行動作的擴充版面配置。
+
+</p>
+<p> 在這段時間之後,通知會退回至通知欄。
+如果通知的<a href="#correctly_set_and_manage_notification_priority">優先順序</a>被標記為「高」、「最大」或「全螢幕」,就會取得預告通知。
+</p>
+
+<p><b>預告通知的好範例</b></p>
+
+<ul>
+ <li> 使用裝置時有來電</li>
+ <li> 使用裝置時啟動鬧鐘功能</li>
+ <li> 新簡訊</li>
+ <li> 電池電力不足</li>
+</ul>
+
+<h2 style="clear:both" id="guidelines">指導方針</h2>
+
+
+<h3 id="MakeItPersonal">提供個人設定</h3>
+
+<p>針對由另一人傳送項目的通知
+(如郵件或狀態更新),使用
+{@link android.app.Notification.Builder#setLargeIcon setLargeIcon()} 納入對方提供的影像。也將對方的資訊附加至通知的中繼資料中
+(請參閱 {@link android.app.Notification#EXTRA_PEOPLE})。</p>
+
+<p>您通知的主要圖示仍會顯示,這樣使用者就可以將主要圖示與狀態列中的可見圖示關聯起來。
+
+</p>
+
+
+<img src="{@docRoot}images/android-5.0/notifications/Triggered.png" alt="" width="311px" />
+<p style="margin-top:10px" class="img-caption">
+ 通知會顯示觸發通知的人及其傳送的內容。
+</p>
+
+
+<h3 id="navigate_to_the_right_place">導覽至正確的地方</h3>
+
+<p>當輕觸通知的本文時
+(在動作按鈕之外),請將您的應用程式開啟至使用者可以檢視的地方,並根據通知中引用資料進行動作。
+
+在多數情況下,這將是單一資料項目 (如訊息) 的詳細資料檢視,但如果通知被堆疊時,也可能會是概述檢視。
+
+如果您的應用程式會將使用者帶到應用程式頂層之下的任何地方,則請將導覽過程插入應用程式的返回堆疊中,這可以讓使用者能夠按下系統的返回按鈕,返回至頂層。
+
+如需詳細資訊,請見<a href="{@docRoot}design/patterns/navigation.html#into-your-app">導覽</a>設計模式中的「透過主螢幕視窗小工具和通知,導覽至您的應用程式」<em></em>。
+
+</p>
+
+<h3 id="correctly_set_and_manage_notification_priority">正確設定和管理通知優先順序
+
+</h3>
+
+<p>Android 支援對通知設定優先順序的旗標。此旗標可與其他通知旗標比較,影響通知顯示的位置,這有助於確保使用者一律會先看到最重要的通知。
+
+
+在發佈通知時,您可以從以下優先順序等級選擇:
+
+</p>
+<table>
+ <tr>
+ <td class="tab0">
+<p><strong>優先順序</strong></p>
+</td>
+ <td class="tab0">
+<p><strong>使用</strong></p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>MAX</code></p>
+</td>
+ <td class="tab1">
+<p>用於關鍵且緊急的通知,警示使用者注意此通知具時效性或必須在繼續特定工作前先解決的情況。
+
+
+</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>HIGH</code></p>
+</td>
+ <td class="tab1">
+<p>主要用於重要通訊,例如內容為使用者特別感興趣的郵件或聊天事件。高優先順序通知會觸發預告通知的顯示。
+
+</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>DEFAULT</code></p>
+</td>
+ <td class="tab1">
+<p>用於不屬於此處所述任何其他優先事項類型的所有通知。</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>LOW</code></p>
+</td>
+ <td class="tab1">
+<p>用於您希望使用者能夠被告知,但不那麼緊急的通知。
+低優先順序通知往往出現在清單的底端,因此適合於公共或間接的社交更新:
+
+使用者已要求針對這類事件通知,但這些通知一律不會優先於緊急或直接通訊。
+
+
+</p>
+</td>
+ </tr>
+ <tr>
+ <td class="tab1">
+<p><code>MIN</code></p>
+</td>
+ <td class="tab1">
+<p>用於內容關聯或背景資訊,例如天氣資訊或內容關聯位置的資訊。最低優先順序通知不會出現在狀態列。
+
+使用者會在展開通知欄時找到這些通知。
+</p>
+</td>
+ </tr>
+</table>
+
+
+<h4 id="how_to_choose_an_appropriate_priority"><strong>如何選擇合適的優先順序</strong>
+
+</h4>
+
+<p><code>DEFAULT</code>、<code>HIGH</code> 和 <code>MAX</code> 為可中斷的優先順序等級,且有打斷使用者正進行動作的風險。
+
+如要避免惹惱您應用程式的使用者,請將可中斷的優先順序保留給下列通知:
+</p>
+
+<ul>
+ <li> 涉及另一人</li>
+ <li> 具時效性</li>
+ <li> 可能會立即變更使用者在現實世界中的行為</li>
+</ul>
+
+<p>對使用者而言,設定為 <code>LOW</code> 和 <code>MIN</code> 的通知仍可能很有價值:
+很多通知 -- 就算不是大多數 -- 並不需要使用者立即注意,或透過振動使用者的手腕加以提醒;但在使用者選擇查看通知時,這些通知仍會包含使用者覺得有價值的資訊。
+
+
+<code>LOW</code> 和 <code>MIN</code>
+ 優先順序通知的準則包含:</p>
+
+<ul>
+ <li> 不會牽涉到別人</li>
+ <li> 不具時效性</li>
+ <li> 包含使用者可能感興趣,但可能在空閒時才會瀏覽的內容
+</li>
+</ul>
+
+
+ <img src="{@docRoot}images/android-5.0/notifications/notifications_pattern_priority.png" alt="" width="700" />
+
+
+<h3 style="clear:both" id="set_a_notification_category">設定通知類別
+</h3>
+
+<p>如果您的通知屬於某個預先定義的類別
+(詳見下列說明),則請據以指派。
+通知欄 (或任何其他通知接聽器) 等系統 UI
+可能會使用此資訊,決定排名和篩選結果。
+</p>
+<table>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_CALL">CATEGORY_CALL</a></code></p>
+</td>
+ <td>
+<p>來電 (語音或視訊) 或類似的同步化通訊要求
+</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_MESSAGE">CATEGORY_MESSAGE</a></code></p>
+</td>
+ <td>
+<p>傳入的直接訊息 (簡訊、即時訊息等)</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_EMAIL">CATEGORY_EMAIL</a></code></p>
+</td>
+ <td>
+<p>非同步大量郵件 (電子郵件)</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_EVENT">CATEGORY_EVENT</a></code></p>
+</td>
+ <td>
+<p>「行事曆」事件</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_PROMO">CATEGORY_PROMO</a></code></p>
+</td>
+ <td>
+<p>宣傳或廣告</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_ALARM">CATEGORY_ALARM</a></code></p>
+</td>
+ <td>
+<p>鬧鐘或計時器</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_PROGRESS">CATEGORY_PROGRESS</a></code></p>
+</td>
+ <td>
+<p>長時間執行的背景操作其進度</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SOCIAL">CATEGORY_SOCIAL</a></code></p>
+</td>
+ <td>
+<p>社交網路或共用更新</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_ERROR">CATEGORY_ERROR</a></code></p>
+</td>
+ <td>
+<p>背景操作或驗證狀態中的錯誤</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_TRANSPORT">CATEGORY_TRANSPORT</a></code></p>
+</td>
+ <td>
+<p>播放的媒體傳輸控制</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SYSTEM">CATEGORY_SYSTEM</a></code></p>
+</td>
+ <td>
+<p>系統或裝置狀態更新。保留供系統使用。</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_SERVICE">CATEGORY_SERVICE</a></code></p>
+</td>
+ <td>
+<p>執行背景服務的表示</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_RECOMMENDATION">CATEGORY_RECOMMENDATION</a></code></p>
+</td>
+ <td>
+<p>針對單一件事的特定、及時建議。例如,新聞應用程式可能會想推薦其認為使用者下一步想要閱讀的新聞報導。
+
+</p>
+</td>
+ </tr>
+ <tr>
+ <td>
+<p><code><a
+href="/reference/android/app/Notification.html#CATEGORY_STATUS">CATEGORY_STATUS</a></code></p>
+</td>
+ <td>
+<p>有關裝置或內容關聯狀態的進行中資訊</p>
+</td>
+ </tr>
+</table>
+
+<h3 id="summarize_your_notifications">概述您的通知</h3>
+
+<p>當您的應用程式嘗試傳送的通知,但已有類型相同的通知仍在等待中,則請針對應用程式將這些相同類型的通知合併為單一概述通知,而不要建立新物件。
+
+</p>
+
+<p>概述通知會建立概述描述,並讓使用者瞭解特定種類的通知有多少數目正在等待處理。
+
+</p>
+
+<div class="col-6">
+
+<p><strong>不要這樣做</strong></p>
+ <img src="{@docRoot}images/android-5.0/notifications/Summarise_Dont.png" alt="" width="311px" />
+</div>
+
+<div>
+<p><strong>請這樣做</strong></p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/Summarise_Do.png" alt="" width="311px" />
+</div>
+
+<p style="clear:left; padding-top:30px; padding-bottom:20px">您可以使用擴充摘要版面配置,針對組成概述的個別通知,提供更多詳細資料。
+
+這種方法可讓使用者更能感覺出哪些通知正處於等待處理,以及是否夠有趣,以便在關聯應用程式中詳細閱讀。
+
+
+
+</p>
+<div class="col-6">
+ <img src="{@docRoot}images/android-5.0/notifications/Stack.png" style="margin-bottom:20px" alt="" width="311px" />
+ <p class="img-caption">
+ 概述實際上是通知的展開和收縮 (使用 <code>InboxStyle</code>)
+ </p>
+</div>
+
+<h3 style="clear:both" id="make_notifications_optional">讓通知成為可選用的
+</h3>
+
+<p>使用者應該總是能夠控制通知。讓使用者可以停用您應用程式的通知,或變更其警示屬性,如鬧鐘聲音或是否要使用振動,方法則是為您的應用程式設定新增通知設定項目。
+
+
+
+</p>
+
+<h3 id="use_distinct_icons">使用易於分辨的的圖示</h3>
+<p>使用者應該能瞄一下通知區域,即可以分辨哪些種類的通知目前正在等待處理。
+
+</p>
+
+<div class="figure">
+ <img src="{@docRoot}images/android-5.0/notifications/ProductIcons.png" alt="" width="420" />
+</div>
+
+ <div><p><strong>請這樣做</strong></p>
+ <p>查看 Android 應用程式圖示,
+Android 應用程式已為您的應用程式提供外觀易於分辨的通知圖示。
+</p>
+
+ <p><strong>請這樣做</strong></p>
+ <p>針對小圖示使用<a href="/design/style/iconography.html#notification">通知圖示樣式</a>,針對您的動作列圖示使用 Material Light <a href="/design/style/iconography.html#action-bar">動作列圖示樣式</a>。
+
+
+
+</p>
+<p ><strong>請這樣做</strong></p>
+<p >讓圖示保持看起來簡單的狀態,避免因過多的詳細資料造成使用者難以看清楚。
+</p>
+
+ <div><p><strong>不要這樣做</strong></p>
+ <p>將任何額外的
+Alpha
+(變暗或淡出)
+置入您的小圖示和動作圖示之中;它們的邊緣可能會有反鋸齒狀,但因為 Android 使用這些圖示做為遮罩
+(也就是說,只使用 Alpha 通道),所以影像通常會以完全透明度來繪製。
+</p>
+
+</div>
+<p style="clear:both"><strong>不要這樣做</strong></p>
+
+<p>使用顏色以區分您與其他人的應用程式。通知圖示應該只是個白色圖示透明背景的背景影像。
+</p>
+
+
+<h3 id="pulse_the_notification_led_appropriately">可以調整通知 LED 適當開啟
+</h3>
+
+<p>許多 Android 裝置具備通知 LED,可用於當螢幕關閉時通知使用者有新事件。
+
+優先順序等級為<code>MAX</code>、<code>HIGH</code> 和 <code>DEFAULT</code> 的通知,
+應該要讓 LED 亮起,而只有低優先順序 (<code>LOW</code> 和 <code>MIN</code>) 的通知則不需要。
+
+</p>
+
+<p>使用者對通知的控制應該延伸到 LED 上。當您使用 DEFAULT_LIGHTS,LED 會亮白色。
+
+除非使用者已明確自訂通知,否則您的通知不應該使用其他顏色。
+
+</p>
+
+<h2 id="building_notifications_that_users_care_about">建立使用者喜歡的通知
+</h2>
+
+<p>若要建立使用者喜歡的應用程式,精心設計您的通知非常重要。通知代表您應用程式的聲音,並有助於您應用程式的個性。
+
+
+非必要或非重要的通知會讓使用者不高興,這會讓他們覺得應用程式想要吸引注目不擇手段,所以請明智地使用通知。
+
+
+</p>
+
+<h3 id="when_to_display_a_notification">顯示通知的時機</h3>
+
+<p>若要建立人們喜歡使用的應用程式,重要的是要體認到使用者的注意與專注是必須加以保護的資源。
+
+雖然 Android 的通知系統已重新設計,儘量降低通知對使用者注意力的影響。但仍然必須警覺,通知會中斷使用者的工作流程。在規劃您的通知時,請先自問:通知是否足夠重要到可以合理地中斷使用者。
+
+
+
+
+
+
+如果您不確定,則讓使用者可以使用您應用程式的通知設定,或調整通知優先順序旗標為 <code>LOW</code> 或 <code>MIN</code>,避免使用者在從事其他工作時因此分心。
+
+
+
+</p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/TimeSensitive.png" alt="" width="311px" />
+ <p style="margin-top:10px" class="img-caption">
+ 具時效性的通知範例
+ </p>
+
+<p>妥善規劃的應用程式只會在必要時才出現,但有幾個情況的確有益於應用程式透過無提示通知中斷使用者的行為。
+</p>
+
+<p>通知主要還是使用於<strong>具時效性時間的事件</strong>,特別是當這些同步事件<strong>涉及其他人</strong>的時候。
+比如說,傳入的聊天是通訊的即時、同步形式:
+
+另一個使用者正主動等待您的回應。
+「行事曆」事件是何時使用通知吸引使用者注意的另一個好例子,因為事件即將發生,而「行事曆」事件通常牽涉到其他人。
+
+
+</p>
+
+<h3 style="clear:both" id="when_not_to_display_a_notification">不顯示通知的時機
+</h3>
+
+<div class="figure" style="margin-top:60px">
+ <img src="{@docRoot}images/android-5.0/notifications/AntiSample1.png" alt="" width="311px" />
+</div>
+
+<p>在許多其他情況下,通知並不適當:</p>
+
+<ul>
+ <li> 當通知並非直接針對使用者,或者資訊並非真正具時效性時,請避免通知使用者。
+
+例如,來自社交網路的非同步與間接更新,通常不是即時中斷的好時機。
+
+
+對於重視這些狀況的使用者,可以讓他們自行選擇加入通知。
+</li>
+ <li> 如果相關的新資訊目前正在螢幕上,則不要建立另一個通知。
+反之,直接在前後關係中使用應用程式本身的 UI 通知使用者有新資訊。
+
+
+ 例如,當使用者正與另一位使用者聊天時,聊天應用程式不應建立系統通知。
+</li>
+ <li> 如果應用程式或系統可以不干擾使用者而解決問題,就不要因為如儲存或同步化資訊,或更新應用程式等低層級的技術操作而中斷使用者活動。
+
+</li>
+ <li> 如果可能的話,就讓應用程式能自行從錯誤恢復,在不需要使用者進行任何動作時,就不要告知他們錯誤而中斷使用者的活動。
+
+</li>
+ <li> 不要建立無實質內容的通知,也不要建立內容僅是在廣告您應用程式的通知。
+
+通知應該要能夠提供實用、及時的新資訊,而非只是為了啟動一個應用程式。
+
+</li>
+ <li> 請不要為了讓您的品牌出現在使用者面前,而建立多餘的通知。
+
+ 這類通知會讓您的使用者感到失望並不願意使用您的應用程式。能夠提供少量的更新資訊並可以吸引使用者注意您應用程式的最佳方式,是開發一個小工具,讓使用者可以選擇放置在主畫面上。
+
+
+
+
+</li>
+</ul>
+
+<h2 style="clear:left" id="interacting_with_notifications">與通知互動
+</h2>
+
+<p>通知可由狀態列上的圖示表示,並可以透過開啟通知匣來存取。
+
+</p>
+
+<p>輕觸通知會開啟相關應用程式,顯示符合通知的詳細資料內容。對通知往左右滑動,可以將通知從通知匣中移除。
+
+</p>
+
+<h3 id="ongoing_notifications">進行中通知</h3>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/MusicPlayback.png" alt="" width="311px" />
+ <p class="img-caption">
+ 因為音樂播放的緣故所以有進行中通知
+ </p>
+</div>
+<p>進行中通知可讓使用者得知在背景中正在進行程序的資訊。例如,音樂播放程式會在通知系統中宣告正在播放的曲目,除非使用者停止曲目,否則就會繼續宣告。
+
+
+
+進行中通知也可以針對如下載檔案或編碼影片等耗時較長的工作,向使用者顯示目前進度。
+
+使用者無法手動將進行中通知從通知匣移除。
+</p>
+
+<h3 id="ongoing_notifications">媒體播放</h3>
+<p>在 Android 5.0 中,鎖定螢幕不會針對已過時的
+{@link android.media.RemoteControlClient} 類別,顯示傳輸控制項。但鎖定螢幕「的確」<em></em>會顯示通知,所以每個應用程式的播放通知,現在都已經是使用者從鎖定狀態控制播放的主要方法。
+
+這個行為可讓應用程式進一步控制以何種方式顯示哪些按鈕,同時無論螢幕是否鎖定,都能為使用者提供一致性的體驗。
+
+
+</p>
+
+<h3 style="clear:both"
+id="dialogs_and_toasts_are_for_feedback_not_notification">對話和快顯通知
+</h3>
+
+<p>您的應用程式目前若不在畫面上,就不應建立對話或快顯通知。
+對話或快顯通知只在使用者於您應用程式內採取動作時產生立即回應時才顯示。至於使用對話與快顯通知的進一步指引,請參閱<a href="/design/patterns/confirming-acknowledging.html">確認和確認完成</a>。
+
+
+
+</p>
+
+<h3>排名和排序</h3>
+
+<p>通知就是新聞,所以基本上是以逆時間順序顯示,同時會針對應用程式指定的通知<a href="#correctly_set_and_manage_notification_priority">優先順序</a>,給與特殊考慮。
+
+
+</p>
+
+<p>通知是鎖定螢幕的重要部分,並會在裝置重新顯示螢幕時明確作用。
+
+鎖定螢幕上的空間有限,所以更重要的是辨別出最緊急或相關的通知。
+
+基於這個理由,Android 針對通知提供了更複雜的排序演算法,並同時考慮:
+
+</p>
+
+<ul>
+ <li> 時間戳記和應用程式指定的優先順序。</li>
+ <li> 通知最近是否以聲音或振動干擾使用者。
+(也就是說,如果電話剛發出一個聲響,而使用者想要知道「剛剛發生什麼事?」,鎖定螢幕應該以瞄一下就能取得通知的方式來回應使用者。
+)
+
+</li>
+ <li> 任何使用 {@link android.app.Notification#EXTRA_PEOPLE} 附加至該通知的人員,尤其是他們是否為標記星號的連絡人。
+</li>
+</ul>
+
+<p>要善用這種排序,請著重於您想要建立的使用者體驗,而非著眼於清單上的任何特定排名位置。
+
+</p>
+
+ <img src="{@docRoot}images/android-5.0/notifications/AntiSample3.png" alt="" width="700px" />
+
+ <p class="img-caption" style="margin-top:10px">Gmail 通知使用預設的優先順序,所以通常排序低於像 Hangouts 等即時訊息應用程式,但當有新郵件進來時,會暫時立即提升。
+
+
+
+
+ </p>
+
+
+<h3>在鎖定螢幕上</h3>
+
+<p>由於通知可見於鎖定螢幕上,因此使用者隱私是特別重要的考量。
+
+通知通常包含敏感資訊,而且不一定要顯示給拿起裝置並打開顯示的任何人。
+
+</p>
+
+<ul>
+ <li> 針對具有安全鎖定螢幕 (PIN、圖案或密碼) 的裝置,介面有公用和私密兩部分。
+公用介面可以顯示在安全鎖定螢幕上,因此任何人都可看見。
+私密介面是鎖定螢幕背後的世界,只在使用者登入裝置時才會顯示。
+</li>
+</ul>
+
+<h3>使用者控制安全鎖定螢幕上顯示的資訊</h3>
+<div class="figure" style="width:311px">
+ <img src="{@docRoot}images/android-5.0/notifications/LockScreen@2x.png" srcset="{@docRoot}images/android-5.0/notifications/LockScreen.png 1x" alt="" width="311px" />
+ <p class="img-caption">
+ 鎖定螢幕上的通知,以及使用者解鎖裝置後顯示的內容。
+ </p>
+</div>
+
+<p>當設定安全鎖定螢幕時,使用者可以選擇隱藏來自安全鎖定螢幕的機密詳細資料。
+在這種情況下,系統 UI 會考慮通知的「可見度」<em></em>等級,判斷可以顯示何種內容。
+
+</p>
+<p> 如要控制可見度等級,可以呼叫
+<code><a
+href="/reference/android/app/Notification.Builder.html#setVisibility(int)">Notification.Builder.setVisibility()</a></code>,並指定下列值之一:
+</p>
+
+<ul>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_PUBLIC">VISIBILITY_PUBLIC</a></code>。
+顯示通知的完整內容。
+ 如果未指定可見度,則這會是系統預設值。</li>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_PRIVATE">VISIBILITY_PRIVATE</a></code>。
+在鎖定螢幕上,顯示這個通知存在的基本資訊,
+包括通知圖示和發佈通知的應用程式。通知詳細資料的其他部分則不會顯示。
+但請記住的下列幾點:
+ <ul>
+ <li> 如果您想要提供您通知的不同公用版本,
+以便顯示在安全鎖定螢幕上,
+請在 <code><a
+href="/reference/android/app/Notification.html#publicVersion">Notification.publicVersion</a></code>
+欄位中提供一個取代的「通知」物件。
+ <li> 此設定可以讓您的應用程式有機會建立內容的改編版本,非常實用但卻不會透露個人資訊。
+考慮簡訊應用程式的例子,
+其通知包含簡訊的文字和傳送者的姓名與連絡人圖示。
+此通知應該是 <code>VISIBILITY_PRIVATE</code>,但 <code>publicVersion</code> 仍包含像「3 個新訊息」等實用資訊,
+但卻又不提供任何其他可用來識別的詳細資料。
+
+ </ul>
+ </li>
+ <li><code><a
+href="/reference/android/app/Notification.html#VISIBILITY_SECRET">Notification.VISIBILITY_SECRET</a></code>。僅顯示最起碼的資訊,
+甚至連通知圖示都排除。</li>
+</ul>
+<h2 style="clear:both" id="notifications_on_android_wear">Android Wear 上的通知
+</h2>
+
+<p>預設情況下,通知和其<em>動作</em>會橋接至穿戴裝置。
+開發人員可以控制哪些通知可從電話橋接至手錶上,
+反之亦然。
+開發人員還可以控制哪些動作可以橋接。如果您的
+應用程式包含
+無法以單一點選完成的動作,
+請在您的穿戴通知上隱藏這些動作
+,或考慮將其連結至穿戴應用程式,
+讓使用者可以在手錶上完成動作。
+</p>
+
+<h4>橋接通知和動作</h4>
+
+<p>例如電話等已連線的裝置,
+可以橋接通知至穿戴裝置,讓通知可以在該處顯示。同樣的,也可以橋接動作,
+這樣使用者就可以直接從穿戴裝置對通知執行動作。</p>
+
+<p><strong>橋接</strong></p>
+
+<ul>
+ <li> 新的即時訊息</li>
+ <li> 例如 +1 等單點選動作,像 Heart</li>
+</ul>
+
+<img src="{@docRoot}images/android-5.0/notifications/WearBasic.png" width="156px" height="156px" alt="" />
+
+<p><strong>請勿橋接</strong></p>
+
+<ul>
+ <li> 新到播客的通知</li>
+ <li> 對應至手錶上不可能執行的動作</li>
+</ul>
+
+
+
+<p><h4>要在穿戴裝置上定義的獨特動作</h4></p>
+
+<p>有些動作只能在穿戴裝置上執行。這些動作包含:</p>
+
+<ul>
+ <li> 罐頭回應的快速清單,例如「會馬上回來」</li>
+ <li> 在手機上開啟</li>
+ <li> 帶出語音輸入畫面的「註解」或「回覆」動作</li>
+ <li> 啟動穿戴裝置特定的應用程式動作</li>
+</ul>
+
+<img src="{@docRoot}images/android-5.0/notifications/ReplyAction.png" width="156px" height="156px" alt="" />
diff --git a/docs/html-intl/intl/zh-tw/preview/api-overview.jd b/docs/html-intl/intl/zh-tw/preview/api-overview.jd
new file mode 100644
index 0000000..f6c5696
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/preview/api-overview.jd
@@ -0,0 +1,521 @@
+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">具備設計風格的 ColorStateList</a></li>
+ <li><a href="#audio">音訊功能</a></li>
+ <li><a href="#video">影片功能</a></li>
+ <li><a href="#camera">相機功能</a>
+ <ol>
+ <li><a href="#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">API 級別 22 到 M 預覽版&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 的意圖系統。此功能讓您能夠將應用程式關聯到您自己的 Web 網域。
+根據這個關聯,平台可以判斷要用來處理特定 Web 連結的預設應用程式,並略過提示使用者選取應用程式的程序。如要深入瞭解如何實作此功能,請參閱<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 金鑰存放區系統</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>前往 [設定] &gt; [安全性] &gt; [指紋]<strong></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>如要設定在成功驗證使用者之後,同一個金鑰可重複使用的逾時時間長度,可在您設定 {@link javax.crypto.KeyGenerator} 或
+{@link java.security.KeyPairGenerator} 時,呼叫新的
+{@code android.security.keystore.KeyGenParameterSpec.setUserAuthenticationValidityDurationSeconds()}
+方法。
+此功能目前適用於對稱式密碼編譯操作。
+</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 "android.service.chooser.chooser_target_service"} 的
+{@code &lt;meta-data&gt;} 元素。
+</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>Home</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">具備設計風格的 ColorStateList</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()} 方法。
+您也可以透過 {@link android.support.v4.content.ContextCompat},在 v4 appcompat 程式庫中取得這些方法。
+</p>
+
+<h2 id="audio">音訊功能</h2>
+
+<p>這個預覽版在 Android 上新增了音訊處理的增強功能,包括: </p>
+<ul>
+ <li>利用新的 {@code android.media.midi} API,來支援 <a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a> 通訊協定。
+使用這些 API 來傳送與接收 MIDI 事件。
+</li>
+ <li>新的 {@code android.media.AudioRecord.Builder} 和 {@code android.media.AudioTrack.Builder}
+類別,可分別建立數位音訊擷取和播放物件,並設定音訊來源和接收屬性來覆寫系統預設值。
+</li>
+ <li>API 勾點,適合用來關聯音訊與輸入裝置。如果您的應用程式允許使用者從連接到 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">閃光燈 API</h3>
+<p>如果相機裝置具有閃光裝置,則您可以呼叫 {@code CameraManager.setTorchMode()}
+方法,在不開啟相機裝置的情況下,開啟或關閉閃光裝置的閃光模式。應用程式不具備閃光裝置或相機裝置的獨佔擁有權。
+每當相機裝置變成無法使用時,或者,當其他相機資源讓閃光變成無法使用時,閃光模式也會關閉且變成無法使用。
+
+其他應用程式也會呼叫 {@code setTorchMode()}
+來關閉閃光模式。關閉最後一個開啟閃光模式的應用程式時,閃光模式即會關閉。
+</p>
+
+<p>您可以呼叫
+{@code CameraManager.registerTorchCallback()} 方法,來註冊回呼要收到有關閃光模式狀態的通知。第一次註冊回呼時,會立即使用所有目前已知具有閃光裝置之相機裝置的閃光模式來呼叫它。
+
+如果成功開啟或關閉閃光模式,即會叫用
+{@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>使用
+{@code DevicePolicyManager.setStatusBarEnabledState()} 方法,來停用或重新啟用狀態列 (包括快速設定、通知,以及啟動 Google 即時資訊的導覽向上滑動手勢)。
+</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>裝置擁有者現在可以使用 {@link android.content.pm.PackageInstaller}
+API (與 Google Play for Work 無關) 自動安裝與解除安裝應用程式。
+您現在可以透過裝置擁有者佈建裝置,該裝置擁有者可在不與使用者互動的情況下擷取並安裝應用程式。
+如要在不啟用 Google 帳戶的情況下輕觸一次就能佈建 Kiosk 或其他這類裝置,這個功能非常有用。
+</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()} 來設定系統更新原則,裝置擁有者現在可以自動接受系統更新 (例如,在 Kiosk 裝置的案例中),或者延後更新,並防止使用者進行更新,最多 30 天。
+
+因此,系統管理員可以設定必須取得更新的每日時間範圍 ,例如,在 Kiosk 裝置處於未使用狀態時。
+在系統更新可供使用時,系統就會檢查工作原則控制器應用程式是否已設定系統更新原則,並據以運作。
+
+
+</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)。
+NFC 程式設計人員應用程式可以在已重設裝置來解除鎖定 FRP 並佈建裝置之後提供這些參數,而不需使用先前設定的 Google 帳戶。
+
+如果您並未修改這些參數,FRP 會就地保留,並防止裝置在沒有先前啟用的 Google 認證的情況下啟用。
+
+
+<p>此外,裝置擁有者可以在 Google Play 服務上設定應用程式限制,來指定可用來解除鎖定 FRP 的替代 Google 帳戶,以取代已在裝置上啟用的帳戶。
+</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} 方法,針對可在 [設定] &gt; [資料]<strong></strong> 使用量中看見的資料使用量統計資料進行查詢。
+系統會自動授與設定檔擁有者權限來查詢他們所管理之設定檔上的資料,在此同時,裝置擁有者會取得受管理的主要使用者之使用量資料的存取權限。
+
+</li>
+<li><strong>執行階段權限管理:</strong>
+<p>設定檔或裝置擁有者可以使用
+{@code DevicePolicyManager.setPermissionPolicy()},針對所有應用程式的所有執行階段要求設定權限原則,以提示使用者授與一般權限,或者以無訊息方式自動授與或拒絕該權限。
+
+如果設定了後項原則,使用者就無法在應用程式權限畫面的 [設定]<strong></strong> 中,修改設定檔或裝置擁有者所做的選項。
+
+</p></li>
+<li><strong>設定中的 VPN:</strong>VPN 應用程式現在可以在 [設定] &gt; [更多] &gt; [VPN]<strong></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/zh-tw/preview/behavior-changes.jd b/docs/html-intl/intl/zh-tw/preview/behavior-changes.jd
new file mode 100644
index 0000000..405aea1
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/preview/behavior-changes.jd
@@ -0,0 +1,402 @@
+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">休眠</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">API 級別 22 到 M 預覽版&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">休眠</h3>
+<p>如果拔除裝置電源並關閉螢幕使其保持靜止狀態一段時間,該裝置即會進入「休眠」<em></em>模式,它會嘗試讓系統保持睡眠狀態。
+在此模式中,裝置會在短期間內定期繼續執行正常操作,因此,會進行應用程式同步處理,而系統可以執行任何待處理的操作。
+
+</p>
+
+<p>處於休眠狀態時,下列限制會套用到您的應用程式:</p>
+<ul>
+<li>除非您的應用程式接收到高優先順序的 Google 雲端通訊活動訊號 (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>當裝置離開休眠狀態時,就會執行所有待處理的工作和同步處理。</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 雲端通訊</a>版本讓您能夠指定高優先順序的訊息。
+
+
+如果您的應用程式收到高優先順序的 GCM 訊息,即使裝置處於休眠狀態,系統還是會授與它短暫的網路存取權限。
+
+</p>
+
+<p>如需如何在您的應用程式中測試休眠的祕訣,請參閱<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 雲端通訊</a> (GCM) 版本讓您能夠指定高優先順序的訊息。
+
+
+如果您的應用程式收到高優先順序的 GCM 訊息,即使應用程式處於閒置狀態,系統還是會授與它短暫的網路存取權限。
+
+</p>
+
+<p>如需如何在您的應用程式中測試應用程式待命的祕訣,請參閱<a href="{@docRoot}preview/testing/guide.html#doze-standby">測試指南</a>。
+
+ </p>
+
+<h2 id="behavior-adoptable-storage">可採用的儲存裝置</h2>
+<p>
+使用這個預覽版時,使用者可以採用<em></em>像是 SD 卡的外部儲存裝置。採用外部儲存裝置會加密並格式化裝置,使其可如內部儲存空間般運作。
+此功能讓使用者能夠在儲存裝置之間移動應用程式和這些應用程式的私人資料。
+移動應用程式時,系統會採用宣示說明中的 <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 磁碟機 (這個磁碟機是透過 USB On-The-Go (OTG) 纜線連接到 Android 裝置):
+</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>當使用者在您的應用程式中選取文字時,您現在可以在<a href="http://www.google.com/design/spec/patterns/selection.html#selection-text-selection" class="external-link">浮動工具列</a>中顯示文字選取動作,例如,剪下<em></em>、複製<em></em>及貼上<em></em>。
+
+使用者互動實作類似於針對內容關聯動作列所做的實作,如<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()},然後在傳回的
+{@link android.support.v7.app.AppCompatDelegate} 物件中呼叫
+{@code android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled()},並將輸入參數設定為 {@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>
+在以前,如果應用程式使用
+{@link android.net.wifi.WifiManager#enableNetwork(int,boolean) enableNetwork()} 搭配
+{@code disableAllOthers=true} 設定來強制裝置連接到特定的 Wi-Fi 網路,裝置即會中斷與其他網路的連線,例如行動數據。
+在這個預覽版中,裝置不再中斷與這類其他網路的連線。如果您應用程式的 {@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>
+變更目前的使用者會導致先前的使用者帳戶所擁有之應用程式的使用中相機用戶端被撤出。
+相機的存取權受限於目前裝置使用者所擁有的使用者設定檔。例如,這實際上表示「訪客」帳戶在使用者切換到不同帳戶之後,將無法保留使用相機子系統的執行中處理程序。
+
+
+</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()} 方法且您想要覆寫存取檢查,請搭配已設定為 {@code true} 的輸入參數呼叫
+{@link java.lang.reflect.Constructor#setAccessible(boolean) setAccessible()} 方法。
+
+
+
+如果您的應用程式使用 <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">公開的 Bug 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 設定。
+只要尚未針對使用者設定 {@link android.os.UserManager} 常數
+{@link android.os.UserManager#DISALLOW_CONFIG_WIFI},該使用者就仍能建立和修改他們自己的 WiFi 設定。
+</li>
+<li><strong>透過 Google 帳戶新增來下載工作原則控制器:</strong>在將要求透過工作原則控制器 (WPC) 應用程式進行管理的 Google 帳戶新增到受管理內容以外的裝置時,新增帳戶流程現在會提示使用者安裝適當的 WPC。這個行為也適用於在初始裝置設定精靈中透過 [設定] &gt; [帳戶]<strong></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/zh-tw/preview/features/runtime-permissions.jd b/docs/html-intl/intl/zh-tw/preview/features/runtime-permissions.jd
new file mode 100644
index 0000000..cf756aa
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/preview/features/runtime-permissions.jd
@@ -0,0 +1,794 @@
+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 介面,務必要先確定呼叫端具備存取該資料的必要權限後,再 Proxy 權限。
+
+
+</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> 畫面,然後選擇 [應用程式] &gt;<strong></strong>
+
+ <i>app_name</i> &gt; [權限]<strong></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(<i>permission_name</i>)</code>。由於使用者可以隨時撤銷應用程式的權限,即使應用程式知道使用者已授與該權限,還是應該執行此檢查。
+
+
+例如,如果使用者想要使用應用程式拍攝相片,應用程式會呼叫 <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>
+ 例如,攝影應用程式可能想要使用定位服務,以便將相片加上地理標籤。
+一般使用者可能不明白相片可以包含定位資訊,而不明白為何攝影應用程式會想要知道位置。
+
+在這種情況下,在呼叫 <code>requestPermissions()</code>「之前」<em></em>,將此功能的相關資訊告訴使用者會是不錯的想法。
+
+
+</p>
+
+<p>
+ 您可以將這些要求與應用程式教學課程結合來完成此作業。教學課程可依序顯示應用程式的各項功能,並可以同時說明需要哪些權限。
+
+例如,攝影應用程式的教學課程可以示範「與聯絡人分享相片」功能,接著告訴使用者需要提供權限,應用程式才能看到使用者的聯絡人。
+
+
+接著,應用程式可以呼叫 <code>requestPermissions()</code>,要求使用者提供該存取權。
+當然,並非每位使用者都會依照教學課程執行動作,所以您仍需要在應用程式的正常操作期間檢查和要求權限。
+
+
+</p>
diff --git a/docs/html-intl/intl/zh-tw/preview/overview.jd b/docs/html-intl/intl/zh-tw/preview/overview.jd
new file mode 100644
index 0000000..63cde32
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/preview/overview.jd
@@ -0,0 +1,362 @@
+page.title=程式總覽
+page.metaDescription=歡迎使用 Android M 開發人員預覽版,本程式提供為新版 Android 測試和最佳化您應用程式所需的一切。
+page.image=images/cards/card-preview_16-9_2x.png
+page.tags="preview", "developer", "android"
+
+@jd:body
+
+<p>
+ 歡迎使用「Android M 開發人員預覽版」<strong></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 (適用於電視) ,以及模擬器上執行和測試您的應用程式。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 最新的平台程式碼
+ </h5>
+
+ <p>
+ 我們將在預覽版期間提供多次更新,讓您能夠針對最新的平台變更進行測試。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 透過 OTA 傳遞更新
+ </h5>
+
+ <p>
+ 在您將裝置刷新為初始預覽版之後,就能以無線方式取得更新。
+
+ </p>
+ </div>
+ </div>
+
+ <div class="cols">
+
+
+ <div class="col-4of12">
+ <h5>
+ 新行為和功能
+ </h5>
+
+ <p>
+ 儘早開始開發以支援新的平台行為,例如新的執行階段權限模型和省電功能。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 開發人員限時優先回報問題
+ </h5>
+
+ <p>
+ 在前幾個星期內,我們將讓開發人員優先回報問題,因此請盡快測試並提供意見反應。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 意見反應與支援
+ </h5>
+
+ <p>
+ 使用<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 日開始執行,直到我們將在 2015 年第 3 季正式發行之前發行的最終版 Android M SDK。
+
+
+</p>
+
+<p>
+ 我們將在主要的開發里程碑為您的測試裝置提供更新。
+ 里程碑暫定如下
+</p>
+
+<ul>
+ <li>
+ <strong>預覽版&nbsp;1</strong> (初始預覽版,五月下旬)、
+ </li>
+
+ <li>
+ <strong>預覽版&nbsp;2</strong> (六月下旬/七月上旬) 及
+ </li>
+
+ <li>
+ <strong>預覽版&nbsp;3</strong> (接近最終版,七月下旬)
+ </li>
+</ul>
+
+<p>
+ 這些更新最終會成為「最終版 SDK」<strong></strong> (稍後於第 3 季),為新版 Android 提供正式的 API,以及最終的系統行為和功能。
+
+
+</p>
+
+<p>
+ 當您在 Android M 上測試和開發時,強烈建議您在預覽版更新發行時立即更新,讓「您的開發環境保持在最新狀態」<strong></strong>。
+
+ 為了讓程序更簡單,我們將對更新為預覽版建置的裝置<strong>以無線 (OTA) 方式提供更新</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 管理器」下載以下元件:
+</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>
+ 您可以從<a href="download.html">下載頁面</a>下載適用於 Nexus 裝置的以下硬體系統映像:
+
+</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>
+ 適用於目前 M 開發人員預覽版的<a href="{@docRoot}preview/support.html#release-notes">版本資訊</a>,包括變更資訊與差異報告。
+
+ </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>是您能<strong>與其他 Android M 開發人員聯絡</strong>的 Google+ 社群。您可以分享有關 Android M 的觀察或想法,或尋找解答。
+
+
+
+ </li>
+</ul>
+
+
+<h2 id="preview_apis_and_publishing">
+ 目標設定、預覽版 API 及發行
+</h2>
+
+<p>
+ Android M 開發人員預覽版是開發專用的版本,而且<strong>沒有標準的 API 層級</strong>。
+如果您想要選擇退出相容性行為以測試您的應用程式 (強烈建議),您可以將應用程式的 <code><a href=
+ "/guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a></code> 設定為 <code>“MNC”</code>,就能以 M 開發人員預覽版為目標。
+
+
+
+</p>
+
+<p>
+ Android M 開發人員預覽版提供<strong>預覽版 API</strong> &mdash; 在最終版 SDK (目前規劃在 2015 年第三季) 發行之前的都不是正式 API。
+
+這表示您可以預期 API 會隨時間而有些許變更,特別是程式一開始的幾週。<strong></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>,針對 Nexus 5、6、9 及 Player 刷新最新的 M 開發人員預覽版系統映像。
+
+在您刷新開發裝置之後,預覽版更新將以無線 (OTA) 更新</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/zh-tw/training/basics/activity-lifecycle/index.jd b/docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/index.jd
new file mode 100644
index 0000000..4225184
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/index.jd
@@ -0,0 +1,72 @@
+page.title=管理應用行為顯示生命週期
+page.tags=應用行為顯示生命週期
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+
+<h2>相依性和先決條件</h2>
+<ul>
+ <li>如何建立 Android 專案 (請參閱<a href="{@docRoot}training/basics/firstapp/creating-project.html">建立 Android
+專案</a>)</li>
+</ul>
+
+
+<h2>您也應該閱讀</h2>
+<ul>
+ <li><a href="{@docRoot}guide/components/activities.html">應用行為顯示</a></li>
+</ul>
+
+
+<h2>試試看</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">下載示範</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>使用者在應用程式內部、由內到外、由外到內執行導覽時,應用程式中的 {@link android.app.Activity} 執行個體會在生命週期的不同狀態之間進行轉換。
+
+例如,在您的應用行為顯示首次啟動時,會進入系統的前景,並成為使用者的焦點。
+
+在此過程中,Android 系統會針對設定使用者介面與其他元件所在的應用行為顯示,呼叫一系列生命週期方法。
+若使用者執行的行為會啟動其他應用行為顯示或切換至其他應用程式,系統會在您的應用行為顯示進入背景 (在此處應用行為顯示將不再可見,但執行個體及其狀態保持不變) 時,針對該應用行為顯示呼叫另一組生命週期方法。
+
+
+</p>
+
+<p>在生命週期回呼方法內,您可以宣告在使用者離開並重新進入應用行為顯示時,應用行為顯示採用的行為。
+例如,若您建置串流影片播放器,可能會在使用者切換至其他應用程式時暫停影片播放,並終止網路連線。在使用者返回時,您可以重新連接至網路,讓使用者從先前暫停的位置繼續播放影片。
+
+
+</p>
+
+<p>本課程將說明每個 {@link
+android.app.Activity} 執行個體都會接收的生命週期重要回呼方法,並說明如何使用這些方法,以便應用行為顯示的運作能符合使用者的預期,而且在應用行為顯示不需要系統資源時不耗用系統資源。
+</p>
+
+<h2>課程</h2>
+
+<dl>
+ <dt><b><a href="starting.html">啟動應用行為顯示</a></b></dt>
+ <dd>了解應用行為顯示生命週期的有關基本概念、使用者啟動應用程式的方式,以及建立基本應用行為顯示的執行方式。
+</dd>
+ <dt><b><a href="pausing.html">暫停並繼續應用行為顯示</a></b></dt>
+ <dd>了解應用行為顯示暫停 (遭部分遮蓋) 與繼續時的狀況,以及在這些狀態變更期間應執行的操作。
+</dd>
+ <dt><b><a href="stopping.html">停止並重新啟動應用行為顯示</a></b></dt>
+ <dd>了解在使用者完全離開應用行為顯示與返回應用行為顯示時的狀況。</dd>
+ <dt><b><a href="recreating.html">重新建立應用行為顯示</a></b></dt>
+ <dd>了解在應用行為顯示遭終結時的狀況,以及如何在需要時重新建置應用行為顯示狀態。
+</dd>
+</dl>
+
diff --git a/docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/pausing.jd b/docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/pausing.jd
new file mode 100644
index 0000000..8c0843d
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/pausing.jd
@@ -0,0 +1,147 @@
+page.title=暫停並繼續應用行為顯示
+page.tags=應用行為顯示生命週期
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>本課程示範</h2>
+ <ol>
+ <li><a href="#Pause">暫停您的應用行為顯示</a></li>
+ <li><a href="#Resume">繼續您的應用行為顯示</a></li>
+ </ol>
+
+ <h2>您也應該閱讀</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">應用行為顯示</a>
+ </li>
+ </ul>
+
+<h2>試試看</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">下載示範</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>在應用程式正常使用期間,有時前景應用行為顯示會受到其他視覺元件的遮蓋,導致該應用行為顯示<em>暫停</em>。
+例如,若開啟半透明的應用行為顯示 (諸如採用對話方塊風格的應用行為顯示),前一個應用行為顯示會暫停。
+只要應用行為顯示仍部分可見,但目前並非焦點,就會保持暫停狀態。
+</p>
+
+<p>但是,若應用行為顯示完全遭遮蓋且不可見,則會<em>停止</em> (下一課將對此進行討論)。
+</p>
+
+<p>在您的應用行為顯示進入暫停狀態時,系統會針對您的 {@link android.app.Activity} 呼叫 {@link
+android.app.Activity#onPause onPause()} 方法,您可藉此停止在暫停時不應繼續的進行中行為 (例如影片),或保留使用者持續離開您的應用程式時應永久儲存的資訊。若使用者從暫停狀態返回至您的應用行為顯示,系統會繼續執行該應用行為顯示,並呼叫 {@link android.app.Activity#onResume onResume()} 方法。
+
+
+
+</p>
+
+<p class="note"><strong>注意:</strong>若您的應用行為顯示收到對 {@link
+android.app.Activity#onPause()} 的呼叫,可能表示該應用行為顯示將暫停片刻,隨後使用者會將焦點重新移到您的應用行為顯示上。
+但是,這通常首先表示使用者離開您的應用行為顯示。
+</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-paused.png" />
+<p class="img-caption"><strong>圖 1.</strong>若半透明的應用行為顯示遮蓋您的應用行為顯示,系統會呼叫 {@link android.app.Activity#onPause onPause()},您的應用行為顯示會進行等候 (狀態為「已暫停」) (1)。
+
+若使用者在應用行為顯示仍處於暫停狀態時返回至應用行為顯示,系統將呼叫 {@link android.app.Activity#onResume onResume()} (2)。
+</p>
+
+
+<h2 id="Pause">暫停您的應用行為顯示</h2>
+
+<p>若系統為您的應用行為顯示呼叫 {@link android.app.Activity#onPause()},嚴格來說意味著您的應用行為顯示仍是部分可見,但多數情況下表示使用者離開應用行為顯示,該應用行為顯示很快將進入「已停止」狀態。
+
+通常,您應使用 {@link android.app.Activity#onPause()} 回呼執行以下操作:
+</p>
+
+<ul>
+ <li>停止動畫或會耗用 CPU 資源的其他進行中行為。</li>
+ <li>認可未儲存的變更,但是只有在使用者希望離開時永久儲存此類變更 (例如電子郵件草稿) 的情況下才執行此操作。
+</li>
+ <li>釋放系統資源,例如廣播接收器、感應器 (如 GPS) 的控點,或釋放在您的應用行為顯示暫停時可能影響電池使用壽命 (且使用者不再需要) 的資源。
+
+</li>
+</ul>
+
+<p>例如,若您的應用程式使用 {@link android.hardware.Camera},則使用 {@link android.app.Activity#onPause()} 方法可以良好地將其釋放。
+</p>
+
+<pre>
+&#64;Override
+public void onPause() {
+ super.onPause(); // Always call the superclass method first
+
+ // Release the Camera because we don't need it when paused
+ // and other activities might need to use it.
+ if (mCamera != null) {
+ mCamera.release()
+ mCamera = null;
+ }
+}
+</pre>
+
+<p>一般而言,您<strong>不</strong>應使用 {@link android.app.Activity#onPause()} 將使用者變更 (例如表單中輸入的個人資訊) 儲存至永久儲存空間。
+只有在您確信使用者希望自動儲存變更 (例如在起草電子郵件的情況下) 時,才應將使用者變更保留在 {@link android.app.Activity#onPause()} 中的永久儲存空間內。但是在 {@link
+android.app.Activity#onPause()} 期間,您應避免執行耗用大量 CPU 資源的工作 (例如寫入至資料庫),因為這會降低向下一個應用行為顯示進行視覺轉換的速度 (您應改為在 {@link android.app.Activity#onStop onStop()} 期間執行高負荷的關機作業)。
+
+
+
+
+</p>
+
+<p>對於使用 {@link android.app.Activity#onPause
+onPause()} 方法執行的作業,應保持相對簡單,以便在您的應用行為顯示實際正在停止的情況下,實現向使用者下一個目標的快速轉換。
+</p>
+
+<p class="note"><strong>注意:</strong>您的應用行為顯示暫停後,{@link
+android.app.Activity} 執行個體將保留在記憶體中,應用行為顯示繼續時將重新呼叫該執行個體。您無需重新初始化在使用回呼方法 (導致產生「已繼續」狀態) 期間建立的元件。
+
+</p>
+
+
+
+<h2 id="Resume">繼續您的應用行為顯示</h2>
+
+<p>若使用者從「已暫停」狀態繼續執行您的應用行為顯示,系統會呼叫 {@link
+android.app.Activity#onResume()} 方法。</p>
+
+<p>請注意,每次您的應用行為顯示進入前景時 (包括第一次建立該應用行為顯示時),系統都會呼叫此方法。
+因此,您應實作 {@link
+android.app.Activity#onResume()},以初始化您在 {@link
+android.app.Activity#onPause()} 期間釋放的元件,並執行每次應用行為顯示進入「已繼續」狀態時必須進行的其他初始化 (例如開始播放動畫,以及對只有在應用行為顯示具有使用者焦點時才使用的元件進行初始化)。
+
+</p>
+
+<p>以下 {@link android.app.Activity#onResume()} 範例是上述 {@link android.app.Activity#onPause()} 範例的對應,會針對應用行為顯示暫停時釋放的相機執行初始化。
+
+</p>
+
+<pre>
+&#64;Override
+public void onResume() {
+ super.onResume(); // Always call the superclass method first
+
+ // Get the Camera instance as the activity achieves full user focus
+ if (mCamera == null) {
+ initializeCamera(); // Local method to handle camera init
+ }
+}
+</pre>
+
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/recreating.jd b/docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/recreating.jd
new file mode 100644
index 0000000..4b0efda
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/recreating.jd
@@ -0,0 +1,178 @@
+page.title=重新建立應用行為顯示
+page.tags=應用行為顯示生命週期
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>本課程示範</h2>
+ <ol>
+ <li><a href="#SaveState">儲存您的應用行為顯示狀態</a></li>
+ <li><a href="#RestoreState">還原您的應用行為顯示狀態</a></li>
+ </ol>
+
+ <h2>您也應該閱讀</h2>
+ <ul>
+ <li><a href="{@docRoot}training/basics/supporting-devices/screens.html">支援不同的螢幕</a>
+</li>
+ <li><a href="{@docRoot}guide/topics/resources/runtime-changes.html">處理執行階段變更</a></li>
+ <li><a href="{@docRoot}guide/components/activities.html">應用行為顯示</a>
+ </li>
+ </ul>
+
+ </div>
+</div>
+
+<p>在某些情況下,您的應用行為顯示會因應用程式的正常行為 (例如使用者按下 <em>[返回]</em>按鈕) 而遭終結,或您的應用行為顯示透過呼叫 {@link android.app.Activity#finish()} 來示意自身發生毀損。
+
+此外,在您的應用行為顯示目前已停止並且已長時間未使用時,或者在系統因前景應用行為顯示需要更多資源而必須關閉背景程序以復原記憶體時,系統可能會終結您的應用行為顯示。
+
+</p>
+
+<p>若您的應用行為顯示因使用者按下 <em>[返回]</em>按鈕而遭終結,或應用行為顯示將自身終止,則系統中該 {@link android.app.Activity} 執行個體的概念將永遠無法實現,因為該行為表示不再需要此應用行為顯示。
+
+但是,若系統因系統限制 (而非因應用程式正常行為) 而終結應用行為顯示,則雖然實際的 {@link android.app.Activity} 執行個體不會執行,但系統會記住該執行個體曾經存在,因此若使用者重新導覽至該應用行為顯示,系統會使用對應用行為顯示遭終結時的狀態進行描述的一組已儲存資料,建立該應用行為顯示的新執行個體。
+
+
+
+系統用於還原先前狀態的已儲存資料稱為「執行個體狀態」,是 {@link android.os.Bundle} 物件中所儲存索引鍵值配對的集合。
+
+</p>
+
+<p class="caution"><strong>注意:</strong>使用者每次旋轉螢幕時,都會終結並重新建立您的應用行為顯示。
+螢幕變更方向時,系統會終結並重新建立前景應用行為顯示,因為螢幕組態已變更,您的應用行為顯示可能需要載入替代資源 (例如版面配置)。
+
+</p>
+
+<p>依預設,系統會使用 {@link android.os.Bundle} 執行個體狀態將每個 {@link android.view.View} 物件的有關資訊 (例如輸入至 {@link android.widget.EditText} 物件中的文字值) 儲存至您的應用行為顯示版面配置中。
+
+因此,若終結並重新建立您的應用行為顯示執行個體,會將版面配置的狀態還原為其先前的狀態,您無需輸入任何程式碼。
+
+但是,您可能希望還原更多的應用行為顯示狀態資訊,例如成員變數 (可追蹤應用行為顯示中使用者的進度)。
+
+</p>
+
+<p class="note"><strong>注意:</strong>若要讓 Android 系統還原應用行為顯示中檢視的狀態,
+<strong>每個檢視都必須具有唯一的 ID</strong> (由 <a href="{@docRoot}reference/android/view/View.html#attr_android:id">{@code
+android:id}</a> 屬性提供)。
+</p>
+
+<p>若要儲存有關應用行為顯示狀態的其他資料,您必須覆寫 {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} 回呼方法。系統會在使用者離開您的應用行為顯示時呼叫此方法,並向其傳遞 {@link android.os.Bundle} 物件 (在您的應用行為顯示遭到非預期終結時將儲存該物件)。
+
+
+
+若系統必須稍後重新建立應用行為顯示執行個體,會將同一 {@link
+android.os.Bundle} 物件傳遞至 {@link android.app.Activity#onRestoreInstanceState
+onRestoreInstanceState()} 與 {@link android.app.Activity#onCreate onCreate()} 方法。
+
+</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-savestate.png" />
+<p class="img-caption"><strong>圖 2.</strong>系統開始停止您的應用行為顯示時,會呼叫 {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} (1),因此您可以指定在必須重新建立 {@link android.app.Activity} 執行個體時希望儲存的其他狀態資料。若已終結應用行為顯示,且必須重新建立該執行個體,系統會將 (1) 中定義的狀態資料傳遞至 {@link android.app.Activity#onCreate onCreate()} 方法 (2) 與 {@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} 方法 (3)。
+
+
+
+
+
+
+</p>
+
+
+
+<h2 id="SaveState">儲存您的應用行為顯示狀態</h2>
+
+<p>在您的應用行為顯示開始停止時,系統會呼叫 {@link android.app.Activity#onSaveInstanceState
+onSaveInstanceState()},因此您的應用行為顯示可將狀態資訊與索引鍵值配對的集合一併儲存。
+此方法的預設實作會儲存應用行為顯示的檢視層次狀態相關資訊 (例如 {@link android.widget.EditText} 小工具中的文字或 {@link android.widget.ListView} 的捲動位置)。
+
+</p>
+
+<p>若要儲存應用行為顯示的其他狀態資訊,您必須實作 {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()},並將索引鍵值配對新增至 {@link android.os.Bundle} 物件。
+
+例如:</p>
+
+<pre>
+static final String STATE_SCORE = "playerScore";
+static final String STATE_LEVEL = "playerLevel";
+...
+
+&#64;Override
+public void onSaveInstanceState(Bundle savedInstanceState) {
+ // Save the user's current game state
+ savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
+ savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
+
+ // Always call the superclass so it can save the view hierarchy state
+ super.onSaveInstanceState(savedInstanceState);
+}
+</pre>
+
+<p class="caution"><strong>注意:</strong>請始終呼叫 {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()} 的超級類別實作,以便預設實作可儲存檢視階層的狀態。
+</p>
+
+
+
+<h2 id="RestoreState">還原您的應用行為顯示狀態</h2>
+
+<p>在重新建立先前終結的應用行為顯示時,您可以從 {@link android.os.Bundle} 復原系統向您的應用行為顯示傳遞的已儲存狀態。
+
+{@link android.app.Activity#onCreate onCreate()} 與 {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} 回呼方法會接收同一 {@link android.os.Bundle} (包含執行個體狀態資訊)。
+</p>
+
+<p>由於不論系統是建立應用行為顯示的新執行個體,還是重新建立先前的執行個體,都會呼叫 {@link android.app.Activity#onCreate onCreate()} 方法,因此您必須先檢查狀態 {@link android.os.Bundle} 是否為 null,然後再嘗試對其進行讀取。
+
+若其為 null,表示系統正在建立應用行為顯示的新執行個體,否則表示正在還原先前已終結的執行個體。
+
+</p>
+
+<p>例如,以下為您展示了如何在 {@link android.app.Activity#onCreate
+onCreate()} 中還原某些狀態資料:</p>
+
+<pre>
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState); // Always call the superclass first
+
+ // Check whether we're recreating a previously destroyed instance
+ if (savedInstanceState != null) {
+ // Restore value of members from saved state
+ mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
+ mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
+ } else {
+ // Probably initialize members with default values for a new instance
+ }
+ ...
+}
+</pre>
+
+<p>您可以選擇並非在 {@link android.app.Activity#onCreate onCreate()} 期間還原狀態,而是實作 {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()},系統會在呼叫 {@link android.app.Activity#onStart()} 方法後呼叫該項目。
+
+只有存在要還原的已儲存狀態時,系統才會呼叫 {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()},因此您無需檢查 {@link android.os.Bundle} 是否為 null:
+</p>
+
+<pre>
+public void onRestoreInstanceState(Bundle savedInstanceState) {
+ // Always call the superclass so it can restore the view hierarchy
+ super.onRestoreInstanceState(savedInstanceState);
+
+ // Restore state members from saved instance
+ mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
+ mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
+}
+</pre>
+
+<p class="caution"><strong>注意:</strong>請始終呼叫 {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} 的超級類別實作,以便預設實作可還原檢視階層的狀態。
+</p>
+
+<p>若要詳細了解因執行階段中的重新啟動事件 (例如在旋轉螢幕時) 而重新建立應用行為顯示,請閱讀<a href="{@docRoot}guide/topics/resources/runtime-changes.html">處理執行階段變更</a>。
+</p>
+
diff --git a/docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/starting.jd b/docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/starting.jd
new file mode 100644
index 0000000..3453ac5
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/starting.jd
@@ -0,0 +1,285 @@
+page.title=啟動應用行為顯示
+page.tags=應用行為顯示的生命週期
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>本課程示範</h2>
+<ol>
+ <li><a href="#lifecycle-states">了解生命週期回呼</a></li>
+ <li><a href="#launching-activity">指定您應用程式的啟動器應用行為顯示</a></li>
+ <li><a href="#Create">建立新執行個體</a></li>
+ <li><a href="#Destroy">終結應用行為顯示</a></li>
+</ol>
+
+ <h2>您也應該閱讀</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">應用行為顯示</a></li>
+ </ul>
+
+<h2>試試看</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">下載示範</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>在其他程式設計範例中,使用 {@code main()} 方法啟動應用程式,而 Android 系統與此不同,透過呼叫與 {@link android.app.Activity} 執行個體生命週期的特定階段相對應的特定回呼方法,在該執行個體中啟動程式碼。
+
+
+可以採用一系列回呼方法啟動應用行為顯示,也可以採用一系列回呼方法終結應用行為顯示。
+</p>
+
+<p>本課程將概述最重要的生命週期方法,並為您展示如何處理第一個生命週期回呼 (該回呼會建立應用行為顯示的新執行個體)。
+</p>
+
+
+
+<h2 id="lifecycle-states">了解生命週期回呼</h2>
+
+<p>在應用行為顯示的生命週期內,系統會以類似於階梯金字塔的順序,呼叫一組核心生命週期方法。
+換言之,應用行為顯示生命週期的每個階段都是金字塔上的一個台階。
+在系統建立新應用行為顯示執行個體時,每個回呼方法都會將應用行為顯示狀態向頂部移動一個台階。
+在金字塔的頂部,應用行為顯示將在前景中執行,使用者可以與應用行為顯示互動。
+</p>
+
+<p>在使用者開始離開應用行為顯示時,系統會呼叫可將應用行為顯示狀態沿金字塔下移的其他方法,以終結應用行為顯示。
+在某些狀況下,應用行為顯示會沿金字塔僅移動部分台階,然後開始等候 (例如若使用者切換至其他應用程式),應用行為顯示可以由此移回頂部 (若使用者返回該應用行為顯示),並在使用者先前停止的位置繼續。
+
+
+</p>
+
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle.png" />
+<p class="img-caption"><strong>圖 1.</strong>應用行為顯示生命週期的簡化圖例 (以階梯金字塔表示)。
+此圖例顯示,對於讓應用行為顯示向頂部的「已繼續」狀態邁上一個台階所用的每個回呼,都存在可讓應用行為顯示下移的回呼方法。
+
+應用行為顯示也可以從「已暫停」及「已停止」狀態返回至「已繼續」狀態。
+</p>
+
+
+<p>視應用行為顯示的複雜程度而定,您可能不需要實作所有生命週期方法。
+但是,請務必了解每個生命週期方法,並實作能確保您的應用程式以使用者預期方式運作的生命週期方法。
+正確實作應用行為顯示生命週期方法可確保您的應用程式以多種方式良好運作,包括:
+</p>
+<ul>
+ <li>使用您的應用程式時,若使用者接電話或切換至其他應用程式,不會發生當機。
+</li>
+ <li>使用者未主動使用時,不會耗用寶貴的系統資源。
+</li>
+ <li>若使用者離開您的應用程式並在稍後返回,使用者的進度不會遺失。
+</li>
+ <li>若螢幕方向在橫向與直向之間旋轉,不會發生當機或遺失使用者的進度。
+</li>
+</ul>
+
+<!--
+<p class="table-caption"><strong>Table 1.</strong> Activity lifecycle state pairs and callback
+methods.</p>
+<table>
+ <tr>
+ <th scope="col">Lifecycle State</th>
+ <th scope="col">Startup Method</th>
+ <th scope="col">Teardown Method</th>
+ </tr>
+ <tr>
+ <td>Created / Destroyed</td>
+ <td>{@link android.app.Activity#onCreate onCreate()}</td>
+ <td>{@link android.app.Activity#onDestroy()}</td>
+ </tr>
+ <tr>
+ <td>Started / Stopped</td>
+ <td>{@link android.app.Activity#onStart()}</td>
+ <td>{@link android.app.Activity#onStop()}</td>
+ </tr>
+ <tr>
+ <td>Resumed / Resumed</td>
+ <td>{@link android.app.Activity#onResume()}</td>
+ <td>{@link android.app.Activity#onPause()}</td>
+ </tr>
+</table>
+-->
+
+<p>在以下課程中您將了解到,某些情況下應用行為顯示會在不同的狀態之間進行轉換,如圖 1 所示。
+但是在這些狀態中,只有三種可以是靜態狀態。
+換言之,應用行為顯示長時間存在時,只能具備這三種狀態的其中之一:
+</p>
+<dl>
+ <dt>已繼續</dt>
+ <dd>若具備此狀態,應用行為顯示將位於前景中,使用者可以與應用行為顯示互動 (有時也稱為「執行中」狀態)。
+</dd>
+ <dt>已暫停</dt>
+ <dd>若具備此狀態,該應用行為顯示的一部分會遭其他應用行為顯示遮蓋,&mdash;
+位於前景中的其他應用行為顯示處於半透明狀態,或未覆蓋整個螢幕。已暫停的應用行為顯示不會接收使用者輸入,也無法執行任何程式碼。
+
+ <dt>已停止</dt>
+ <dd>若具備此狀態,應用行為顯示將完全隱藏,使用者無法看到;會將該應用行為顯示視為位於背景中。
+停止後,會保留應用行為顯示執行個體及其所有狀態資訊 (例如成員變數),但其無法執行任何程式碼。
+</dd>
+</dl>
+
+<p>其他狀態 (「已建立」與「已啟動」) 都是暫時狀態,系統透過呼叫下一個生命週期回呼方法,會從這些狀態快速移至下一個狀態。
+換言之,在系統呼叫 {@link android.app.Activity#onCreate onCreate()} 後,會快速呼叫 {@link
+android.app.Activity#onStart()},然後快速呼叫 {@link
+android.app.Activity#onResume()}。
+</p>
+
+<p>以上所述是應用行為顯示的基本生命週期。現在您將開始了解某些特定生命週期行為。
+</p>
+
+
+
+<h2 id="launching-activity">指定您應用程式的啟動器應用行為顯示</h2>
+
+<p>若使用者從主螢幕中選取您的應用程式圖示,系統會針對應用程式中您已宣告作為「啟動器」(或「主程式」) 應用行為顯示的 {@link android.app.Activity},呼叫 {@link
+android.app.Activity#onCreate onCreate()} 方法。
+此應用行為顯示將作為您應用程式使用者介面的主要進入點。
+</p>
+
+<p>您可以定義 Android 宣示說明檔案 (即 <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">{@code AndroidManifest.xml}</a>,位於您專案目錄的根目錄中) 中用作主要應用行為顯示的應用行為顯示。
+</p>
+
+<p>必須在宣示說明中使用 <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a> (包括 {@link
+android.content.Intent#ACTION_MAIN MAIN} 行為與 {@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} 類別) 宣告您應用程式的主要應用行為顯示。
+例如:</p>
+
+<pre>
+&lt;activity android:name=".MainActivity" android:label="&#64;string/app_name">
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.MAIN" />
+ &lt;category android:name="android.intent.category.LAUNCHER" />
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p class="note"><strong>注意:</strong>使用 Android SDK 工具建立新 Android 專案時,預設專案檔案包括宣示說明中使用此篩選器宣告的 {@link android.app.Activity} 類別。
+
+</p>
+
+<p>若未針對您的其中一項應用行為顯示宣告 {@link android.content.Intent#ACTION_MAIN MAIN} 行為或 {@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} 類別,您的應用程式圖示將不會顯示在主螢幕的應用程式清單中。
+
+</p>
+
+
+
+<h2 id="Create">建立新執行個體</h2>
+
+<p>大多數應用程式都包括多項不同的應用行為顯示,使用者可以藉此執行不同的行為。不論應用行為顯示是使用者按一下應用程式圖示時建立的主要應用行為顯示,還是您的應用程式為回應使用者行為而啟動的其他應用行為顯示,系統都會呼叫 {@link android.app.Activity#onCreate onCreate()} 方法,以建立 {@link android.app.Activity} 的每個新執行個體。
+
+
+
+</p>
+
+<p>您必須實作 {@link android.app.Activity#onCreate onCreate()} 方法以執行基本的應用程式啟動邏輯,在應用行為顯示的整個生命週期內,該操作應僅執行一次。
+例如,實作 {@link android.app.Activity#onCreate onCreate()} 將定義使用者介面,並且可能會啟動某些類別範圍的變數。
+
+</p>
+
+<p>例如,以下 {@link android.app.Activity#onCreate onCreate()} 方法範例展示的一些程式碼將執行應用行為顯示的某些基礎設定,諸如宣告使用者介面 (在 XML 版面配置檔案中定義)、定義成員變數,以及設定 UI 的某些部分。
+
+
+</p>
+
+<pre>
+TextView mTextView; // Member variable for text view in the layout
+
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Set the user interface layout for this Activity
+ // The layout file is defined in the project res/layout/main_activity.xml file
+ setContentView(R.layout.main_activity);
+
+ // Initialize member TextView so we can manipulate it later
+ mTextView = (TextView) findViewById(R.id.text_message);
+
+ // Make sure we're running on Honeycomb or higher to use ActionBar APIs
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ // For the main activity, make sure the app icon in the action bar
+ // does not behave as a button
+ ActionBar actionBar = getActionBar();
+ actionBar.setHomeButtonEnabled(false);
+ }
+}
+</pre>
+
+<p class="caution"><strong>注意:</strong>僅在 Android 2.0 (API 層級為 5) 及更高版本中,可以透過此方式使用 {@link android.os.Build.VERSION#SDK_INT} 防止舊版系統執行新 API。
+
+在舊版系統中,將發生執行階段例外狀況。</p>
+
+<p>{@link android.app.Activity#onCreate onCreate()} 執行完成後,系統會連續快速呼叫 {@link android.app.Activity#onStart()} 與 {@link android.app.Activity#onResume()} 方法。
+
+您的應用行為顯示永遠不會具備「已建立」或「已啟動」狀態。嚴格來說,在呼叫 {@link android.app.Activity#onStart()} 時,使用者可以看到應用行為顯示,但隨後會快速呼叫 {@link android.app.Activity#onResume()},應用行為顯示將保持「已繼續」狀態,直到發生某些狀況 (例如接聽電話、使用者導覽至其他應用行為顯示,或裝置螢幕關閉) 變更該狀態為止。
+
+
+
+</p>
+
+<p>在後續的其他課程中,您將了解在應用行為顯示的生命週期期間,其他啟動方法 ({@link
+android.app.Activity#onStart()} 與 {@link android.app.Activity#onResume()}) 在用於從「已暫停」或「已停止」狀態繼續執行應用行為顯示時如何提供助益。
+</p>
+
+<p class="note"><strong>注意:</strong>{@link android.app.Activity#onCreate onCreate()} 方法包括稱為 <code>savedInstanceState</code> 的參數,在有關<a href="recreating.html">重新建立應用行為顯示</a>的後續課程中將討論該參數。
+
+</p>
+
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-create.png" />
+<p class="img-caption"><strong>圖 2.</strong>應用行為顯示生命週期結構的另一個圖例 (著重展示系統建立應用行為顯示的新執行個體時依次呼叫的三個主要回呼:{@link android.app.Activity#onCreate onCreate()}、{@link
+android.app.Activity#onStart()} 及 {@link android.app.Activity#onResume()}。
+
+完成這一系列的回呼後,應用行為顯示將具備「已繼續」狀態,此時使用者可以與應用行為顯示互動,直到使用者切換至其他應用行為顯示為止。
+
+</p>
+
+
+
+
+
+
+
+<h2 id="Destroy">終結應用行為顯示</h2>
+
+<p>應用行為顯示的第一個生命週期回呼是 {@link android.app.Activity#onCreate
+onCreate()},最後一個回呼是 {@link android.app.Activity#onDestroy}。系統針對您的應用行為顯示呼叫此方法作為最終訊號,表示正從系統記憶體中完全移除您的應用行為顯示執行個體。
+
+</p>
+
+<p>大多數應用程式不需要實作此方法,因為區域類別參考與應用行為顯示一併終結,您的應用行為顯示應在 {@link
+android.app.Activity#onPause} 與 {@link android.app.Activity#onStop} 期間執行大多數清理。
+但是,若您的應用行為顯示包括 {@link
+android.app.Activity#onCreate onCreate()} 期間建立的背景執行緒,或包括其他長時間執行的資源 (若未正確關閉,可能會導致記憶體流失),您應在 {@link
+android.app.Activity#onDestroy} 期間終止這些執行緒或資源。
+
+</p>
+
+<pre>
+&#64;Override
+public void onDestroy() {
+ super.onDestroy(); // Always call the superclass
+
+ // Stop method tracing that the activity started during onCreate()
+ android.os.Debug.stopMethodTracing();
+}
+</pre>
+
+<p class="note"><strong>注意:</strong>在所有情況下,系統會在已呼叫 {@link android.app.Activity#onPause} 與 {@link
+android.app.Activity#onStop} 後呼叫 {@link android.app.Activity#onDestroy},但在 {@link android.app.Activity#onCreate onCreate()} 方法中呼叫 {@link
+android.app.Activity#finish()} 的情況除外。
+
+在某些情況下 (例如您應用行為顯示的執行目的在於臨時確定是否啟動其他應用行為顯示),您可能會從 {@link
+android.app.Activity#onCreate onCreate()} 中呼叫 {@link android.app.Activity#finish()} 以終結應用行為顯示。
+若是如此,系統會立即呼叫 {@link android.app.Activity#onDestroy},而不會呼叫其他任何生命週期方法。
+
+</p>
diff --git a/docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/stopping.jd b/docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/stopping.jd
new file mode 100644
index 0000000..a2da5ca
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/training/basics/activity-lifecycle/stopping.jd
@@ -0,0 +1,187 @@
+page.title=停止並重新啟動應用行為顯示
+page.tags=應用行為顯示生命週期
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>本課程示範</h2>
+ <ol>
+ <li><a href="#Stop">停止您的應用行為顯示</a></li>
+ <li><a href="#Start">啟動/重新啟動您的應用行為顯示</a></li>
+ </ol>
+
+ <h2>您也應該閱讀</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/activities.html">應用行為顯示</a>
+ </li>
+ </ul>
+
+<h2>試試看</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">下載示範</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>正確停止並重新啟動您的應用行為顯示是應用行為顯示生命週期內的重要程序,該程序可確保使用者感知您的應用程式在持續運作,而且不會遺失進度。在以下一些重要情況下,會停止並重新啟動您的應用行為顯示:
+
+</p>
+
+<ul>
+ <li>使用者開啟 [最近的應用程式] 視窗,並從您的應用程式切換至其他應用程式。在您的應用程式內,目前位於前景中的應用行為顯示將停止。
+若使用者從主螢幕啟動器圖示或 [最近的應用程式] 視窗返回至您的應用程式,應用行為顯示將重新啟動。
+</li>
+ <li>使用者在您的應用程式中執行啟動新應用行為顯示的行為。建立第二個應用行為顯示時,目前的應用行為顯示將停止。
+若使用者隨後按下 <em>[返回]</em> 按鈕,第一個應用行為顯示將重新啟動。
+</li>
+ <li>使用者在其電話上使用您的應用程式時,會接聽電話。</li>
+</ul>
+
+<p>{@link android.app.Activity} 類別可提供兩種生命週期方法,即 {@link
+android.app.Activity#onStop()} 與 {@link android.app.Activity#onRestart()},您可藉此明確處理如何停止並重新啟動您的應用行為顯示控點。
+處於暫停狀態時,會發生部分 UI 受阻的狀況,但停止狀態與此不同,可保證 UI 不再可見,使用者的焦點在於獨立的應用行為顯示 (或完全獨立的應用程式) 中。
+
+</p>
+
+<p class="note"><strong>注意:</strong>由於在您的 {@link android.app.Activity} 執行個體停止時,系統會將其保留在系統記憶體中,因此您可能完全不需要實作 {@link android.app.Activity#onStop()} 與 {@link android.app.Activity#onRestart()} (甚至 {@link
+android.app.Activity#onStart()}) 方法。
+
+對於相對簡單的大多數應用行為顯示,應用行為顯示會正常停止並重新啟動,您可能只需要使用 {@link
+android.app.Activity#onPause()} 暫停進行中的行為,並與系統資源中斷連線。
+</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-stopped.png" />
+<p class="img-caption"><strong>圖 1.</strong>使用者離開您的應用行為顯示時,系統將呼叫 {@link android.app.Activity#onStop onStop()} 以停止應用行為顯示 (1)。
+若使用者在停止應用行為顯示時返回,系統將呼叫 {@link android.app.Activity#onRestart onRestart()} (2),然後快速呼叫 {@link android.app.Activity#onStart onStart()} (3) 與 {@link
+android.app.Activity#onResume()} (4)。
+
+請注意,不論何種狀況導致應用行為顯示停止,系統始終會先呼叫 {@link android.app.Activity#onPause onPause()},然後呼叫 {@link
+android.app.Activity#onStop onStop()}。
+</p>
+
+
+
+<h2 id="Stop">停止您的應用行為顯示</h2>
+
+<p>您的應用行為顯示收到對 {@link android.app.Activity#onStop()} 方法的呼叫時,將不再可見,並會在使用者不使用時釋放不需要的幾乎所有資源。
+
+在停止您的應用行為顯示後,若系統需要復原系統記憶體,可能會終結執行個體。
+在極少數狀況下,系統可能只會終止應用程式的程序,而不會呼叫應用行為顯示的最終 {@link android.app.Activity#onDestroy()} 回呼,因此請您務必使用 {@link android.app.Activity#onStop()} 釋放可能導致記憶體流失的資源。
+
+</p>
+
+<p>雖然會先呼叫 {@link android.app.Activity#onPause onPause()} 方法,然後呼叫 {@link android.app.Activity#onStop()},但是您應使用 {@link android.app.Activity#onStop onStop()} 執行規模更大、耗用 CPU 資源更多的關閉作業,諸如將資訊寫入至資料庫。
+
+
+</p>
+
+<p>例如,以下範例展示了 {@link android.app.Activity#onStop onStop()} 的實作,該實作將註記草稿的內容儲存至永續性儲存體:
+</p>
+
+<!-- TODO: Find a better example for onStop, because this kind of thing should probably use a
+separate thread but that's too complicated to show here. -->
+<pre>
+&#64;Override
+protected void onStop() {
+ super.onStop(); // Always call the superclass method first
+
+ // Save the note's current draft, because the activity is stopping
+ // and we want to be sure the current note progress isn't lost.
+ ContentValues values = new ContentValues();
+ values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
+ values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());
+
+ getContentResolver().update(
+ mUri, // The URI for the note to update.
+ values, // The map of column names and new values to apply to them.
+ null, // No SELECT criteria are used.
+ null // No WHERE columns are used.
+ );
+}
+</pre>
+
+<p>您的應用行為顯示停止後,{@link android.app.Activity} 物件將保留在記憶體中,應用行為顯示繼續時將重新呼叫該物件。
+您無需重新初始化在使用回呼方法 (導致產生「已繼續」狀態) 期間建立的元件。
+此外,系統還會追蹤版面配置中每個 {@link android.view.View} 的目前狀態,因此若使用者在 {@link android.widget.EditText} 小工具中輸入文字,將保留該內容,您無需對其執行儲存與還原。
+
+
+</p>
+
+<p class="note"><strong>注意:</strong>即使系統在您的應用行為顯示停止時將其終結,該應用行為顯示仍在 {@link android.os.Bundle} (索引鍵值配對的二進位大型物件) 中保留 {@link android.view.View} 物件 (例如 {@link
+android.widget.EditText} 中的文字) 的狀態,若使用者重新導覽至應用行為顯示的同一執行個體,會還原這些物件 (<a href="recreating.html">下一課</a>將更詳細地討論在終結並重新建立您的應用行為顯示時使用 {@link android.os.Bundle} 儲存其他狀態資料)。
+
+
+</p>
+
+
+
+<h2 id="Start">啟動/重新啟動您的應用行為顯示</h2>
+
+<p>您的應用行為顯示從停止狀態回到前景中時,會收到對 {@link android.app.Activity#onRestart()} 的呼叫。
+此外,系統還會呼叫 {@link
+android.app.Activity#onStart()} 方法,每次您的應用行為顯示變為可見時 (不論是重新啟動還是第一次建立),都會執行此操作。
+但是,只有在應用行為顯示從停止狀態繼續時,才會呼叫 {@link
+android.app.Activity#onRestart()} 方法,因此,您可將其用於執行只有在先前停止但未終結應用行為顯示時才需要執行的特殊還原工作。
+
+</p>
+
+<p>應用程式需要使用 {@link android.app.Activity#onRestart()} 來還原應用行為顯示狀態的狀況並不常見,因此針對適用於普通應用程式的這一方法,不存在任何指導方針。
+
+但是,由於您的 {@link android.app.Activity#onStop()} 方法將基本上清除應用行為顯示的所有資源,因此在應用行為顯示重新啟動時,您需要重新啟動這些資源。
+
+此外,在首次建立應用行為顯示時 (此時不存在既有的應用行為顯示執行個體),您也需要重新啟動這些資源。
+因此,您通常應使用 {@link android.app.Activity#onStart()} 回呼方法作為 {@link android.app.Activity#onStop()} 方法的對應,因為系統在建立您的應用行為顯示以及從停止狀態重新啟動應用行為顯示時,都會呼叫 {@link
+android.app.Activity#onStart()}。
+
+
+</p>
+
+<p>例如,由於使用者可能離開應用程式很長時間後才回到應用程式,因此使用 {@link android.app.Activity#onStart()} 方法可以良好地驗證所需的系統功能是否已啟用:
+
+</p>
+
+<pre>
+&#64;Override
+protected void onStart() {
+ super.onStart(); // Always call the superclass method first
+
+ // The activity is either being restarted or started for the first time
+ // so this is where we should make sure that GPS is enabled
+ LocationManager locationManager =
+ (LocationManager) getSystemService(Context.LOCATION_SERVICE);
+ boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
+
+ if (!gpsEnabled) {
+ // Create a dialog here that requests the user to enable GPS, and use an intent
+ // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action
+ // to take the user to the Settings screen to enable GPS when they click "OK"
+ }
+}
+
+&#64;Override
+protected void onRestart() {
+ super.onRestart(); // Always call the superclass method first
+
+ // Activity being restarted from stopped state
+}
+</pre>
+
+
+
+
+<p>系統終結您的應用行為顯示時,會針對您的 {@link android.app.Activity} 呼叫 {@link android.app.Activity#onDestroy()} 方法。
+由於通常您應該已使用 {@link android.app.Activity#onStop()} 釋放大多數資源,因此在收到對 {@link
+android.app.Activity#onDestroy()} 的呼叫之前,大多數應用程式幾乎都不需要執行操作。
+此方法將為您提供對可能導致記憶體流失的資源執行清理的最後機會,因此您應確保已終結其他執行緒,並確保已停止長時間執行的其他行為 (例如方法追蹤)。
+
+
+</p>
+
diff --git a/docs/html-intl/intl/zh-tw/training/basics/data-storage/databases.jd b/docs/html-intl/intl/zh-tw/training/basics/data-storage/databases.jd
new file mode 100644
index 0000000..f3706f1
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/training/basics/data-storage/databases.jd
@@ -0,0 +1,317 @@
+page.title=在 SQL 資料庫中儲存資料
+page.tags=資料儲存空間
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>本課程示範</h2>
+<ol>
+ <li><a href="#DefineContract">定義結構描述與合約</a></li>
+ <li><a href="#DbHelper">使用 SQL Helper 建立資料庫</a></li>
+ <li><a href="#WriteDbRow">將資訊置入資料庫中</a></li>
+ <li><a href="#ReadDbRow">讀取資料庫中的資訊</a></li>
+ <li><a href="#DeleteDbRow">刪除資料庫中的資訊</a></li>
+ <li><a href="#UpdateDbRow">更新資料庫</a></li>
+</ol>
+
+<h2>您也應該閱讀</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#db">使用資料庫</a></li>
+</ul>
+
+<!--
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/Sample.zip" class="button">Download the sample</a>
+ <p class="filename">Sample.zip</p>
+</div>
+-->
+
+</div>
+</div>
+
+
+<p>對於重複資料或結構化資料 (例如連絡資訊),將其儲存至資料庫是理想的選擇。
+本課程假設您已大體熟悉 SQL 資料庫,並協助您開始在 Android 上使用 SQLite 資料庫。
+
+{@link android.database.sqlite} 套件中提供在 Android 上使用資料庫所需的 API。
+</p>
+
+
+<h2 id="DefineContract">定義結構描述與合約</h2>
+
+<p>SQL 資料庫的其中一項主要準則是結構描述,即針對資料庫組織方式的正式宣告。
+在您建立資料庫所用的 SQL 陳述式中,會反映結構描述。
+您可能會發現,建立伴隨類別 (也稱為<em>合約</em>類別) 會非常有益,該類別會以系統化的自我記錄方式,明確指定結構描述的配置。
+
+</p>
+
+<p>合約類別是常數 (可為 URI、表格與欄定義名稱) 的容器。
+藉由合約類別,您可在同一套件內的所有其他類別中使用相同的常數。
+您可藉此在一個位置變更欄名稱,然後將其傳播到全部程式碼中。
+</p>
+
+<p>組織合約類別的良好方式,是將適用於整個資料庫的全域定義置於類別的根層級,
+然後,針對列舉欄的每個表格建立內部類別。
+</p>
+
+<p class="note"><strong>注意:</strong>透過實作 {@link
+android.provider.BaseColumns} 介面,您的內部類別可繼承主索引鍵欄位 (稱為 {@code _ID}),某些 Android 類別 (諸如 cursor adaptor) 希望其具備該欄位。
+
+此操作並非必需的操作,但是可協助您的資料庫與 Android 架構協調運作。
+</p>
+
+<p>例如,以下程式碼片段會定義單一表格的表格名稱與欄名稱:
+</p>
+
+
+<pre>
+public final class FeedReaderContract {
+ // To prevent someone from accidentally instantiating the contract class,
+ // give it an empty constructor.
+ public FeedReaderContract() {}
+
+ /* Inner class that defines the table contents */
+ public static abstract class FeedEntry implements BaseColumns {
+ public static final String TABLE_NAME = &quot;entry&quot;;
+ public static final String COLUMN_NAME_ENTRY_ID = &quot;entryid&quot;;
+ public static final String COLUMN_NAME_TITLE = &quot;title&quot;;
+ public static final String COLUMN_NAME_SUBTITLE = &quot;subtitle&quot;;
+ ...
+ }
+}
+</pre>
+
+
+
+<h2 id="DbHelper">使用 SQL Helper 建立資料庫</h2>
+
+<p>定義資料庫的外觀之後,您應實作多種方法以建立並維護資料庫與表格。
+以下所示是可建立及刪除表格的某些典型陳述式:
+</P>
+
+<pre>
+private static final String TEXT_TYPE = &quot; TEXT&quot;;
+private static final String COMMA_SEP = &quot;,&quot;;
+private static final String SQL_CREATE_ENTRIES =
+ &quot;CREATE TABLE &quot; + FeedEntry.TABLE_NAME + &quot; (&quot; +
+ FeedEntry._ID + &quot; INTEGER PRIMARY KEY,&quot; +
+ FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP +
+ FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
+ ... // Any other options for the CREATE command
+ &quot; )&quot;;
+
+private static final String SQL_DELETE_ENTRIES =
+ &quot;DROP TABLE IF EXISTS &quot; + FeedEntry.TABLE_NAME;
+</pre>
+
+<p>如同在裝置的<a href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">內部儲存空間</a>儲存檔案一樣,Android 會將您的資料庫儲存在與應用程式關聯的私用磁碟空間內。
+
+依預設,其他應用程式無法存取此區域,因此您的資料安全無虞。
+</p>
+
+<p>{@link
+android.database.sqlite.SQLiteOpenHelper} 類別中提供一組有用的 API。若使用此類別取得資料庫的參考,只有在需要執行且<em>並非處於應用程式啟動期間</em>時,系統才會執行資料庫的建立與更新操作 (執行時間可能很長)。
+
+
+
+您只需呼叫 {@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase} 或
+{@link android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} 即可。
+</p>
+
+<p class="note"><strong>注意:</strong>由於這些操作的時間可能很長,因此請確保您在背景執行緒 (例如 {@link android.os.AsyncTask} 或 {@link android.app.IntentService}) 中呼叫 {@link
+android.database.sqlite.SQLiteOpenHelper#getWritableDatabase} 或 {@link
+android.database.sqlite.SQLiteOpenHelper#getReadableDatabase}。
+
+</p>
+
+<p>若要使用 {@link android.database.sqlite.SQLiteOpenHelper},請建立可覆寫 {@link
+android.database.sqlite.SQLiteOpenHelper#onCreate onCreate()}、{@link
+android.database.sqlite.SQLiteOpenHelper#onUpgrade onUpgrade()} 與 {@link
+android.database.sqlite.SQLiteOpenHelper#onOpen onOpen()} 回呼方法的子類別。
+您還可以實作 {@link android.database.sqlite.SQLiteOpenHelper#onDowngrade onDowngrade()},但這並非必需的操作。
+
+</p>
+
+<p>例如,以下展示了 {@link
+android.database.sqlite.SQLiteOpenHelper} (使用上述某些命令) 的實作:</p>
+
+<pre>
+public class FeedReaderDbHelper extends SQLiteOpenHelper {
+ // If you change the database schema, you must increment the database version.
+ public static final int DATABASE_VERSION = 1;
+ public static final String DATABASE_NAME = &quot;FeedReader.db&quot;;
+
+ public FeedReaderDbHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL(SQL_CREATE_ENTRIES);
+ }
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // This database is only a cache for online data, so its upgrade policy is
+ // to simply to discard the data and start over
+ db.execSQL(SQL_DELETE_ENTRIES);
+ onCreate(db);
+ }
+ public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ onUpgrade(db, oldVersion, newVersion);
+ }
+}
+</pre>
+
+<p>若要存取您的資料庫,請啟動 {@link
+android.database.sqlite.SQLiteOpenHelper} 的子類別:</p>
+
+<pre>
+FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());
+</pre>
+
+
+
+
+<h2 id="WriteDbRow">將資訊置入資料庫中</h2>
+
+<p>透過將 {@link android.content.ContentValues} 物件傳遞至 {@link android.database.sqlite.SQLiteDatabase#insert insert()} 方法,可將資料插入至資料庫:
+</p>
+
+<pre>
+// Gets the data repository in write mode
+SQLiteDatabase db = mDbHelper.getWritableDatabase();
+
+// Create a new map of values, where column names are the keys
+ContentValues values = new ContentValues();
+values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id);
+values.put(FeedEntry.COLUMN_NAME_TITLE, title);
+values.put(FeedEntry.COLUMN_NAME_CONTENT, content);
+
+// Insert the new row, returning the primary key value of the new row
+long newRowId;
+newRowId = db.insert(
+ FeedEntry.TABLE_NAME,
+ FeedEntry.COLUMN_NAME_NULLABLE,
+ values);
+</pre>
+
+<p>{@link android.database.sqlite.SQLiteDatabase#insert insert()} 的第一個引數即為表格名稱。
+第二個引數將提供欄的名稱,
+ 在 {@link android.content.ContentValues} 為空時,架構可在該欄中插入 NULL (若您將其設為 {@code "null"},則在無值時,架構不會插入列)。
+
+</p>
+
+
+
+
+<h2 id="ReadDbRow">讀取資料庫中的資訊</h2>
+
+<p>若要從資料庫進行讀取,請使用 {@link android.database.sqlite.SQLiteDatabase#query query()} 方法,然後向其傳遞您的選取條件與所需的欄。該方法會合併 {@link android.database.sqlite.SQLiteDatabase#insert insert()} 與 {@link android.database.sqlite.SQLiteDatabase#update update()} 的元素,對您希望擷取的資料 (而非要插入的資料) 進行定義的欄清單除外。
+
+
+
+將在 {@link android.database.Cursor} 物件中,為您傳回查詢結果。
+</p>
+
+<pre>
+SQLiteDatabase db = mDbHelper.getReadableDatabase();
+
+// Define a <em>projection</em> that specifies which columns from the database
+// you will actually use after this query.
+String[] projection = {
+ FeedEntry._ID,
+ FeedEntry.COLUMN_NAME_TITLE,
+ FeedEntry.COLUMN_NAME_UPDATED,
+ ...
+ };
+
+// How you want the results sorted in the resulting Cursor
+String sortOrder =
+ FeedEntry.COLUMN_NAME_UPDATED + " DESC";
+
+Cursor c = db.query(
+ FeedEntry.TABLE_NAME, // The table to query
+ projection, // The columns to return
+ selection, // The columns for the WHERE clause
+ selectionArgs, // The values for the WHERE clause
+ null, // don't group the rows
+ null, // don't filter by row groups
+ sortOrder // The sort order
+ );
+</pre>
+
+<p>若要查看游標指示的列,請使用其中一種 {@link android.database.Cursor} move 方法,您必須始終先呼叫該方法,然後再開始讀取值。
+一般而言,您應呼叫 {@link android.database.Cursor#moveToFirst} 來執行啟動,如此會將「讀取位置」置於結果中的第一個項目。
+
+對於每列,您可以呼叫其中一種 {@link android.database.Cursor} get 方法 (例如 {@link android.database.Cursor#getString
+getString()} 或 {@link android.database.Cursor#getLong getLong()}),以讀取欄的值。
+對於每種 get 方法,您必須傳遞所需欄的索引位置,可以呼叫 {@link android.database.Cursor#getColumnIndex getColumnIndex()} 或
+{@link android.database.Cursor#getColumnIndexOrThrow getColumnIndexOrThrow()} 取得該位置。例如:
+
+
+</p>
+
+<pre>
+cursor.moveToFirst();
+long itemId = cursor.getLong(
+ cursor.getColumnIndexOrThrow(FeedEntry._ID)
+);
+</pre>
+
+
+
+
+<h2 id="DeleteDbRow">刪除資料庫中的資訊</h2>
+
+<p>若要刪除表格中的列,您需要提供識別這些列的選取條件。
+資料庫 API 可提供建立選取條件的機制 (能防止 SQL 插入)。
+該機制會將選取規格分為選取子句與選取引數。
+子句可定義要查看的欄,您也可以藉此合併欄測試。
+
+引數是要測試的值,繫結在子句中。由於對結果的處理方式不同於規則 SQL 陳述式,因此結果不會遭受 SQL 插入。
+
+</p>
+
+<pre>
+// Define 'where' part of query.
+String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + &quot; LIKE ?&quot;;
+// Specify arguments in placeholder order.
+String[] selectionArgs = { String.valueOf(rowId) };
+// Issue SQL statement.
+db.delete(table_name, selection, selectionArgs);
+</pre>
+
+
+
+<h2 id="UpdateDbRow">更新資料庫</h2>
+
+<p>若您需要修改資料庫值的子集,請使用 {@link
+android.database.sqlite.SQLiteDatabase#update update()} 方法。</p>
+
+<p>更新表格會合併 {@link
+android.database.sqlite.SQLiteDatabase#insert insert()} 的內容值語法與 {@link android.database.sqlite.SQLiteDatabase#delete delete()} 的 {@code where} 語法。
+</p>
+
+<pre>
+SQLiteDatabase db = mDbHelper.getReadableDatabase();
+
+// New value for one column
+ContentValues values = new ContentValues();
+values.put(FeedEntry.COLUMN_NAME_TITLE, title);
+
+// Which row to update, based on the ID
+String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + &quot; LIKE ?&quot;;
+String[] selectionArgs = { String.valueOf(rowId) };
+
+int count = db.update(
+ FeedReaderDbHelper.FeedEntry.TABLE_NAME,
+ values,
+ selection,
+ selectionArgs);
+</pre>
+
diff --git a/docs/html-intl/intl/zh-tw/training/basics/data-storage/files.jd b/docs/html-intl/intl/zh-tw/training/basics/data-storage/files.jd
new file mode 100644
index 0000000..8b8d0a7
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/training/basics/data-storage/files.jd
@@ -0,0 +1,379 @@
+page.title=儲存檔案
+page.tags=資料儲存空間
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>本課程示範</h2>
+<ol>
+ <li><a href="#InternalVsExternalStorage">選擇內部或外部儲存空間</a></li>
+ <li><a href="#GetWritePermission">取得外部儲存空間的權限</a></li>
+ <li><a href="#WriteInternalStorage">將檔案儲存在內部儲存空間</a></li>
+ <li><a href="#WriteExternalStorage">將檔案儲存在外部儲存空間</a></li>
+ <li><a href="#GetFreeSpace">查詢可用空間</a></li>
+ <li><a href="#DeleteFile">刪除檔案</a></li>
+</ol>
+
+<h2>您也應該閱讀</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">使用內部儲存空間</a>
+</li>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#filesExternal">使用外部儲存空間</a>
+</li>
+</ul>
+
+</div>
+</div>
+
+<p>Android 使用的檔案系統類似於其他平台上的磁碟式檔案系統。
+本課程將說明如何透過 Android 檔案系統,使用 {@link java.io.File}
+API 讀取並寫入檔案。
+</p>
+
+<p>{@link java.io.File} 物件適用於以從頭到尾的順序,無一略過地讀取或寫入大量資料。
+該物件的用途很廣,例如非常適用於影像檔案或透過網路交換的項目。
+</p>
+
+<p>本課程將顯示如何在您的應用程式中執行與檔案相關的基本任務。本課程假設您已熟悉 Linux 檔案系統的基本概念,以及
+{@link java.io} 中的標準檔案輸入/輸出 API。
+</p>
+
+
+<h2 id="InternalVsExternalStorage">選擇內部或外部儲存空間</h2>
+
+<p>所有 Android 裝置都有兩個檔案儲存區域:「內部」與「外部」儲存空間。這些名稱源自 Android 發展的初期,當時大多數裝置都提供內建靜態記憶體 (內部儲存空間),以及諸如 micro SD 卡等卸除式儲存媒體 (外部儲存空間)。有些裝置將永久儲存空間分為「內部」與「外部」分割區,因此即使沒有卸除式儲存媒體,也始終存在兩個儲存空間,不論外部儲存空間是否為卸除式媒體,API 行為都相同。以下清單將概述每個儲存空間的狀況。
+
+
+
+
+
+</p>
+
+<div class="col-5" style="margin-left:0">
+<p><b>內部儲存空間:</b></p>
+<ul>
+<li>裝置始終具備內部儲存空間。</li>
+<li>依預設,只有您的應用程式能存取此空間內儲存的檔案。</li>
+<li>使用者解除安裝您的應用程式時,系統會從內部儲存空間移除您應用程式的所有檔案。
+</li>
+</ul>
+<p>若您希望確保使用者與其他應用程式都無法存取您的檔案,使用內部儲存空間是最佳選擇。
+</p>
+</div>
+
+<div class="col-7" style="margin-right:0">
+<p><b>外部儲存空間:</b></p>
+<ul>
+<li>裝置並非始終具備外部儲存空間,因為使用者可以將外部儲存空間掛接為 USB 儲存裝置,在某些情況下也可以從裝置上移除外部儲存空間。
+</li>
+<li>其他應用程式可以讀取外部儲存空間,因此您可能無法對該空間內儲存的檔案遭讀取的情況進行控制。
+</li>
+<li>若使用者解除安裝您的應用程式,只有在您將應用程式的檔案儲存在 {@link android.content.Context#getExternalFilesDir
+getExternalFilesDir()} 的目錄中時,系統才會從外部儲存空間移除您應用程式的檔案。
+</li>
+</ul>
+<p>對於不需要存取限制的檔案,以及您希望與其他應用程式共用的檔案,或允許使用者使用電腦存取的檔案,外部儲存空間是最佳的儲存位置。
+
+</p>
+</div>
+
+
+<p class="note" style="clear:both">
+<strong>秘訣:</strong>雖然應用程式依預設會安裝在內部儲存空間,但是您可以在宣示說明中指定 <a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code
+android:installLocation}</a> 屬性,以便可以將應用程式安裝在外部儲存空間。
+
+在 APK 的大小很大,且使用者的外部儲存空間大於內部儲存空間時,使用者非常喜歡使用該選項。
+如需詳細資訊,請參閱<a href="{@docRoot}guide/topics/data/install-location.html">應用程式安裝位置</a>。
+</p>
+
+
+<h2 id="GetWritePermission">取得外部儲存空間的權限</h2>
+
+<p>若要寫入至外部儲存空間,您必須在<a href="{@docRoot}guide/topics/manifest/manifest-intro.html">宣示說明檔案</a>中要求 {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} 權限:
+</p>
+
+<pre>
+&lt;manifest ...>
+ &lt;uses-permission android:name=&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot; /&gt;
+ ...
+&lt;/manifest>
+</pre>
+
+<div class="caution"><p><strong>注意:</strong>
+目前,所有應用程式無需特殊權限即可讀取外部儲存空間。
+但是,此狀況在將來的版本中將有所變更。若您的應用程式需要讀取外部儲存空間 (但不寫入該空間),您需要宣告 {@link
+android.Manifest.permission#READ_EXTERNAL_STORAGE} 權限。
+若要確保您的應用程式仍以預期方式運作,您應立即宣告此權限,然後變更即會生效。
+</p>
+<pre>
+&lt;manifest ...>
+ &lt;uses-permission android:name=&quot;android.permission.READ_EXTERNAL_STORAGE&quot; /&gt;
+ ...
+&lt;/manifest>
+</pre>
+<p>但是,若您的應用程式使用 {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} 權限,則也以隱含方式具備外部儲存空間讀取權限。
+</p>
+</div>
+
+<p>您無需任何權限即可將檔案儲存在內部儲存空間。
+您的應用程式始終具備內部儲存空間目錄中檔案的讀取與寫入權限。
+</p>
+
+
+
+
+
+<h2 id="WriteInternalStorage">將檔案儲存在內部儲存空間</h2>
+
+<p>將檔案儲存在內部儲存空間時,您可以呼叫以下兩種方法的其中之一,以
+{@link java.io.File} 擷取相應目錄:</p>
+
+<dl>
+ <dt>{@link android.content.Context#getFilesDir}</dt>
+ <dd>傳回代表您應用程式所用內部目錄的 {@link java.io.File}。</dd>
+ <dt>{@link android.content.Context#getCacheDir}</dt>
+ <dd>傳回代表您應用程式暫存快取檔案所用內部目錄的 {@link java.io.File}。
+請確保於不再需要檔案時刪除檔案,並針對您在任何指定時間所用的記憶體數量實作合理的大小限制,例如 1MB。
+
+若系統所用的儲存空間開始不足,可能會刪除您的快取檔案而不提供警告。
+</dd>
+</dl>
+
+<p>若要在上述其中一個目錄中建立新檔案,可以使用 {@link
+java.io.File#File(File,String) File()} 建構函式,然後傳送會指定您內部儲存空間目錄的 {@link java.io.File} (由上述其中一種方法提供)。
+例如:</p>
+
+<pre>
+File file = new File(context.getFilesDir(), filename);
+</pre>
+
+<p>或者,您可以呼叫 {@link
+android.content.Context#openFileOutput openFileOutput()},以取得寫入內部目錄中檔案的 {@link java.io.FileOutputStream}。
+例如,以下展示了如何將某些文字寫入至檔案:
+</p>
+
+<pre>
+String filename = "myfile";
+String string = "Hello world!";
+FileOutputStream outputStream;
+
+try {
+ outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
+ outputStream.write(string.getBytes());
+ outputStream.close();
+} catch (Exception e) {
+ e.printStackTrace();
+}
+</pre>
+
+<p>或者,若您需要快取某些檔案,應改用 {@link
+java.io.File#createTempFile createTempFile()}。例如,以下方法會從 {@link java.net.URL} 中擷取檔案名稱,然後在您應用程式的內部快取目錄中建立具有該名稱的檔案:
+
+</p>
+
+<pre>
+public File getTempFile(Context context, String url) {
+ File file;
+ try {
+ String fileName = Uri.parse(url).getLastPathSegment();
+ file = File.createTempFile(fileName, null, context.getCacheDir());
+ catch (IOException e) {
+ // Error while creating file
+ }
+ return file;
+}
+</pre>
+
+<p class="note"><strong>注意:</strong>
+您應用程式的內部儲存空間目錄由位於 Android 檔案系統特殊位置的應用程式套件名稱指定。嚴格來說,若將檔案模式設為可讀取,則其他應用程式可以讀取您的內部檔案。
+
+
+但是,其他應用程式也需要知道您的應用程式套件名稱與檔案名稱。
+除非您將檔案明確設為可讀取或可寫入,否則其他應用程式無法瀏覽您的內部目錄,也沒有讀取或寫入存取權。
+因此,只要您針對內部儲存空間中的檔案使用 {@link android.content.Context#MODE_PRIVATE},其他應用程式將永遠無法存取這些檔案。
+
+</p>
+
+
+
+
+
+<h2 id="WriteExternalStorage">將檔案儲存在外部儲存空間</h2>
+
+<p>由於可能不具備外部儲存空間&mdash;例如使用者將儲存裝置掛接至 PC,或移除提供外部儲存空間的 SD 卡&mdash;,因此您始終應先驗證磁碟區可用,然後再對其執行存取。
+
+您可以呼叫 {@link android.os.Environment#getExternalStorageState},以查詢外部儲存空間狀態。
+若傳回的狀態等於 {@link android.os.Environment#MEDIA_MOUNTED},則可以讀取並寫入檔案。
+
+例如,以下方法可用於判斷儲存空間的可用性:
+</p>
+
+<pre>
+/* Checks if external storage is available for read and write */
+public boolean isExternalStorageWritable() {
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+ return false;
+}
+
+/* Checks if external storage is available to at least read */
+public boolean isExternalStorageReadable() {
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
+ }
+ return false;
+}
+</pre>
+
+<p>雖然使用者與其他應用程式可以修改外部儲存空間,但是可在外部儲存空間儲存兩種類別的檔案:
+</p>
+
+<dl>
+ <dt>公用檔案</dt>
+ <dd>這些檔案將供其他應用程式及使用者自由使用。
+若使用者解除安裝您的應用程式,這些檔案仍可供使用者使用。
+
+ <p>例如,由您的應用程式拍攝的相片或下載的其他檔案都是公用檔案。</p>
+ </dd>
+ <dt>私用檔案</dt>
+ <dd>這些檔案本屬於您的應用程式,在使用者解除安裝您的應用程式時應予以刪除。雖然嚴格來說,由於這些檔案位於外部儲存空間,因此可供使用者與其他應用程式存取,但實際上這些檔案對於您應用程式之外的使用者並無價值。使用者解除安裝您的應用程式時,系統會刪除您應用程式外部私用目錄中的所有檔案。
+
+
+
+
+ <p>例如,您的應用程式下載的附加資源,或暫存媒體檔案都是私用檔案。</p>
+ </dd>
+</dl>
+
+<p>若您希望將公用檔案儲存在外部儲存空間,請使用
+{@link android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()} 方法取得代表外部儲存空間內相應目錄的 {@link java.io.File}。
+該方法採用對要儲存的檔案類型進行指定 (以便能合理區分這些檔案與其他公用檔案) 的引數,諸如 {@link android.os.Environment#DIRECTORY_MUSIC} 或 {@link
+android.os.Environment#DIRECTORY_PICTURES}。
+
+例如:</p>
+
+<pre>
+public File getAlbumStorageDir(String albumName) {
+ // Get the directory for the user's public pictures directory.
+ File file = new File(Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES), albumName);
+ if (!file.mkdirs()) {
+ Log.e(LOG_TAG, "Directory not created");
+ }
+ return file;
+}
+</pre>
+
+
+<p>若您希望儲存應用程式私用的檔案,可以呼叫 {@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()},然後向其傳送名稱 (表示您希望使用的目錄類型),從而擷取相應目錄。
+
+以此方式建立的每個目錄都會新增至父系目錄 (該目錄會封裝您應用程式的所有外部儲存空間檔案),並在使用者解除安裝您的應用程式時由系統刪除。
+
+</p>
+
+<p>例如,以下所示的方法可用於建立個別相簿的目錄:</p>
+
+<pre>
+public File getAlbumStorageDir(Context context, String albumName) {
+ // Get the directory for the app's private pictures directory.
+ File file = new File(context.getExternalFilesDir(
+ Environment.DIRECTORY_PICTURES), albumName);
+ if (!file.mkdirs()) {
+ Log.e(LOG_TAG, "Directory not created");
+ }
+ return file;
+}
+</pre>
+
+<p>若預先定義的任何子目錄名稱都不適用於您的檔案,您可以改為呼叫 {@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()} 並傳送 {@code null}。此操作
+會傳回外部儲存空間內您應用程式私用目錄的根目錄。</p>
+
+<p>請記住,{@link android.content.Context#getExternalFilesDir getExternalFilesDir()} 會在使用者解除安裝您的應用程式時所刪除的目錄中建立目錄。若您希望要儲存的檔案在使用者解除安裝您的應用程式後仍可用&mdash;例如您的應用程式是相機,而使用者希望保留相片&mdash;,應改用 {@link android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()}。
+
+
+
+</p>
+
+
+<p>不論是將 {@link
+android.os.Environment#getExternalStoragePublicDirectory
+getExternalStoragePublicDirectory()} 用於共用的檔案,還是將 {@link android.content.Context#getExternalFilesDir
+getExternalFilesDir()} 用於您應用程式私用的檔案,請務必使用由 API 常數 (例如 {@link android.os.Environment#DIRECTORY_PICTURES}) 提供的目錄名稱。
+
+
+這些目錄名稱可確保系統正確處理檔案。
+例如,系統媒體掃描程式會將 {@link
+android.os.Environment#DIRECTORY_RINGTONES} 中儲存的檔案視為鈴聲,而非音樂。
+</p>
+
+
+
+
+<h2 id="GetFreeSpace">查詢可用空間</h2>
+
+<p>若您預先知道要儲存的資料量,可以呼叫 {@link java.io.File#getFreeSpace} 或 {@link
+java.io.File#getTotalSpace} 以探明在不會導致 {@link
+java.io.IOException} 的情況下空間是否充足。
+上述方法可分別提供儲存磁碟區內目前可用空間量與空間總量。
+該資訊還可以用於避免填充的儲存磁碟區超過特定臨界值。
+</p>
+
+<p>但是,系統不保證您可以寫入 {@link java.io.File#getFreeSpace} 所示的位元組數量。
+若傳回的數值較您要儲存的資料量略大,或檔案系統的已使用空間不到 90%,則繼續寫入可能是安全的。否則,可能不應寫入儲存空間。
+
+
+</p>
+
+<p class="note"><strong>注意:</strong>在儲存檔案之前,您無需檢查可用空間量。
+您可以嘗試立即寫入檔案,然後在發生 {@link java.io.IOException} 時執行捕捉即可。
+若您不知道需要的確切空間量,可能需要執行該作業。
+例如,若您在儲存檔案之前,將 PNG 影像轉化為 JPEG 以變更檔案的編碼,就不會預先知道檔案的大小。
+
+</p>
+
+
+
+
+<h2 id="DeleteFile">刪除檔案</h2>
+
+<p>不再需要檔案時,應一律刪除檔案。最直接的檔案刪除方式是讓開啟的檔案參考在自身上呼叫 {@link java.io.File#delete}。
+</p>
+
+<pre>
+myFile.delete();
+</pre>
+
+<p>若檔案儲存在內部儲存空間,您也可以呼叫 {@link android.content.Context#deleteFile deleteFile()},讓 {@link android.content.Context} 尋找並刪除檔案:
+</p>
+
+<pre>
+myContext.deleteFile(fileName);
+</pre>
+
+<div class="note">
+<p><strong>注意:</strong>使用者解除安裝您的應用程式時,Android 系統會刪除以下檔案:
+</p>
+<ul>
+<li>您在內部儲存空間儲存的所有檔案</li>
+<li>您使用 {@link
+android.content.Context#getExternalFilesDir getExternalFilesDir()} 在外部儲存空間儲存的所有檔案。</li>
+</ul>
+<p>但是,您應定期手動刪除使用 {@link android.content.Context#getCacheDir()} 建立的所有快取檔案,並定期刪除不再需要的其他檔案。
+
+</p>
+</div>
+
diff --git a/docs/html-intl/intl/zh-tw/training/basics/data-storage/index.jd b/docs/html-intl/intl/zh-tw/training/basics/data-storage/index.jd
new file mode 100644
index 0000000..9ff1fc0
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/training/basics/data-storage/index.jd
@@ -0,0 +1,57 @@
+page.title=儲存資料
+page.tags=資料儲存空間,檔案,sql,資料庫,偏好設定
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>相依性和先決條件</h2>
+<ul>
+ <li>Android 1.6 (API 層級為 4) 或更高版本</li>
+ <li>熟悉地圖的索引鍵值集合</li>
+ <li>熟悉 Java 檔案 I/O API</li>
+ <li>熟悉 SQL 資料庫</li>
+</ul>
+
+<h2>您也應該閱讀</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html">儲存選項</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>在 {@link android.app.Activity#onPause onPause()} 期間,大多數 Android 應用程式都需要儲存資料 (即使僅儲存應用程式狀態的有關資訊),因此使用者的進度不會遺失。
+大多數非一般的應用程式還需要儲存使用者設定,某些應用程式必須管理檔案與資料庫中的大量資訊。
+
+本課程將為您介紹 Android 中的主要資料儲存選項,包括:
+</p>
+
+<ul>
+ <li>將簡單資料類型的索引鍵值配對儲存至共用偏好設定檔案
+</li>
+ <li>將任意檔案儲存至 Android 的檔案系統</li>
+ <li>使用由 SQLite 管理的資料庫</li>
+</ul>
+
+
+<h2>課程</h2>
+
+<dl>
+ <dt><b><a href="shared-preferences.html">儲存索引鍵值組</a></b></dt>
+ <dd>了解如何使用共用的偏好設定檔案將少量資訊儲存至索引鍵值配對。
+</dd>
+
+ <dt><b><a href="files.html">儲存檔案</a></b></dt>
+ <dd>了解如何儲存基本檔案 (例如儲存通常循序讀取的很長一系列資料)。
+</dd>
+
+ <dt><b><a href="databases.html">在 SQL 資料庫中儲存資料</a></b></dt>
+ <dd>了解如何使用 SQLite 資料庫讀取及寫入結構化資料。</dd>
+
+</dl>
diff --git a/docs/html-intl/intl/zh-tw/training/basics/data-storage/shared-preferences.jd b/docs/html-intl/intl/zh-tw/training/basics/data-storage/shared-preferences.jd
new file mode 100644
index 0000000..46f8f20
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/training/basics/data-storage/shared-preferences.jd
@@ -0,0 +1,120 @@
+page.title=儲存索引鍵值組
+page.tags=資料儲存空間
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>本課程示範</h2>
+<ol>
+ <li><a href="#GetSharedPreferences">取得 SharedPreferences 的控點</a></li>
+ <li><a href="#WriteSharedPreference">寫入至共用的偏好設定</a></li>
+ <li><a href="#ReadSharedPreference">從共用的偏好設定進行讀取</a></li>
+</ol>
+
+<h2>您也應該閱讀</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html#pref">使用共用的偏好設定</a></li>
+</ul>
+
+</div>
+</div>
+
+
+<p>若您希望儲存相對較小的索引鍵值集合,應使用 {@link android.content.SharedPreferences} API。
+{@link android.content.SharedPreferences} 物件指向包含索引鍵值配對的檔案,並提供讀取及寫入這些配對的簡單方法。
+
+每個 {@link android.content.SharedPreferences} 檔案都由架構管理,可以是公用或私用檔案。
+
+</p>
+
+<p>本課程將為您展示如何使用 {@link android.content.SharedPreferences} API 儲存及擷取簡單值。
+</p>
+
+<p class="note"><strong>注意:</strong>{@link android.content.SharedPreferences} API 僅用於讀取及寫入索引鍵值配對,不應將其與 {@link android.preference.Preference} API 混淆,後者可協助您建置應用程式設定的使用者介面 (然而這些 API 使用 {@link android.content.SharedPreferences} 作為其儲存應用程式設定的實作方式)。
+
+
+
+如需有關使用 {@link
+android.preference.Preference} API 的資訊,請參閱<a href="{@docRoot}guide/topics/ui/settings.html">設定</a>指南。</p>
+
+<h2 id="GetSharedPreferences">取得 SharedPreferences 的控點</h2>
+
+<p>您可以呼叫以下兩種方法的其中之一,以建立新的共用偏好設定檔案或存取既有的共用偏好設定檔案:
+</p>
+<ul>
+ <li>{@link android.content.Context#getSharedPreferences(String,int)
+getSharedPreferences()} &mdash; 若您需要使用多個共用偏好設定檔案 (根據名稱進行識別,第一個參數將指定名稱),請使用此方法。
+您可以從應用程式中的任何 {@link android.content.Context} 呼叫此方法。
+</li>
+ <li>{@link android.app.Activity#getPreferences(int) getPreferences()} &mdash; 若您只需針對應用行為顯示使用一個共用偏好設定檔案,請從 {@link android.app.Activity} 使用此方法。
+
+由於此方法會擷取屬於該應用行為顯示的預設共用偏好設定檔案,因此您無需提供名稱。
+</li>
+</ul>
+
+<p>例如,以下程式碼會在 {@link android.app.Fragment} 內執行。該程式碼會存取共用偏好設定檔案 (根據資源字串 {@code R.string.preference_file_key} 識別),並使用私用模式開啟該檔案 (因此只有您的應用程式可以存取該檔案)。
+
+
+</p>
+
+<pre>
+Context context = getActivity();
+SharedPreferences sharedPref = context.getSharedPreferences(
+ getString(R.string.preference_file_key), Context.MODE_PRIVATE);
+</pre>
+
+<p>對您的共用偏好設定檔案進行命名時,您應使用能唯一識別您應用程式的名稱,例如 {@code "com.example.myapp.PREFERENCE_FILE_KEY"}
+</p>
+
+<p>或者,若您針對應用行為顯示只需使用一個共用偏好設定檔案,可以使用 {@link android.app.Activity#getPreferences(int) getPreferences()} 方法:
+</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+</pre>
+
+<p class="caution"><strong>注意:</strong>若您使用 {@link android.content.Context#MODE_WORLD_READABLE} 或 {@link
+android.content.Context#MODE_WORLD_WRITEABLE} 建立共用偏好設定檔案,則知道檔案識別碼的其他任何應用程式都能存取您的資料。
+
+</p>
+
+
+<h2 id="WriteSharedPreference">寫入至共用的偏好設定</h2>
+
+<p>若要寫入至共用偏好設定檔案,請針對您的 {@link android.content.SharedPreferences} 呼叫 {@link
+android.content.SharedPreferences#edit},以建立 {@link
+android.content.SharedPreferences.Editor}。</p>
+
+<p>傳遞您希望使用諸如 {@link
+android.content.SharedPreferences.Editor#putInt putInt()} 及 {@link
+android.content.SharedPreferences.Editor#putString putString()} 等方法寫入的索引鍵與值。然後呼叫 {@link
+android.content.SharedPreferences.Editor#commit} 以儲存變更。例如:</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+SharedPreferences.Editor editor = sharedPref.edit();
+editor.putInt(getString(R.string.saved_high_score), newHighScore);
+editor.commit();
+</pre>
+
+
+<h2 id="ReadSharedPreference">從共用的偏好設定進行讀取</h2>
+
+<p>若要擷取共用偏好設定檔案中的值,請呼叫諸如 {@link
+android.content.SharedPreferences#getInt getInt()} 與 {@link
+android.content.SharedPreferences#getString getString()} 等方法,然後針對您希望使用的值提供索引鍵,以及 (可選) 在索引鍵不存在時傳回的預設值。
+
+例如:</p>
+
+<pre>
+SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
+int defaultValue = getResources().getInteger(R.string.saved_high_score_default);
+long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue);
+</pre>
+
diff --git a/docs/html-intl/intl/zh-tw/training/basics/intents/filters.jd b/docs/html-intl/intl/zh-tw/training/basics/intents/filters.jd
new file mode 100644
index 0000000..2088b27
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/training/basics/intents/filters.jd
@@ -0,0 +1,236 @@
+page.title=允許其他應用程式啟動您的應用行為顯示
+page.tags=意圖
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>本課程示範</h2>
+<ol>
+ <li><a href="#AddIntentFilter">新增意圖篩選器</a></li>
+ <li><a href="#HandleIntent">在應用行為顯示中處理意圖</a></li>
+ <li><a href="#ReturnResult">傳回結果</a></li>
+</ol>
+
+<h2>您也應該閱讀</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">共用簡單資料</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">共用檔案</a>
+</ul>
+ </div>
+</div>
+
+<p>前兩課著重說明一個方面:從您的應用程式啟動其他應用程式的應用行為顯示。但是,若您的應用程式能執行可能適用於其他應用程式的行為,則應準備回應其他應用程式的行為要求。
+
+例如,若您建置的社交應用程式可用於與使用者的好友分享訊息或相片,則支援 {@link android.content.Intent#ACTION_SEND} 意圖可為您帶來顯著受益,使用者藉此可從其他應用程式啟動「共用」行為,並啟動您的應用程式來執行該行為。
+
+
+</p>
+
+<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>若您的應用程式安裝在裝置上,系統會識別您的意圖篩選器,並將資訊新增至安裝的所有應用程式都支援的意圖內部目錄中。在應用程式使用隱含意圖呼叫 {@link android.app.Activity#startActivity
+startActivity()} 或 {@link android.app.Activity#startActivityForResult startActivityForResult()} 時,系統會找出能回應意圖的一或多項應用行為顯示。
+
+
+
+</p>
+
+
+
+<h2 id="AddIntentFilter">新增意圖篩選器</h2>
+
+<p>若要正確定義您的應用行為顯示可以處理的意圖,您新增的每個意圖篩選器都應儘可能具體地說明應用行為顯示所接受行為與資料的類型。
+
+</p>
+
+<p>若應用行為顯示的意圖篩選器執行 {@link android.content.Intent} 物件的以下條件,系統會將指定的 {@link android.content.Intent} 傳送至該應用行為顯示:
+</p>
+
+<dl>
+ <dt>行為</dt>
+ <dd>對要執行的行為進行命名的字串。通常是平台所定義值 (例如 {@link android.content.Intent#ACTION_SEND} 或 {@link android.content.Intent#ACTION_VIEW}) 的其中之一。
+
+ <p>請在您的意圖篩選器中使用 <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code &lt;action&gt;}</a> 元素指定此項目。在此元素中指定的值必須是行為的完整字串名稱,而非 API 常數 (請參閱以下範例)。
+
+</p></dd>
+
+ <dt>資料</dt>
+ <dd>對意圖所關聯資料的描述。
+ <p>請在意圖篩選器中使用 <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data&gt;}</a> 元素指定此項目。在此元素中使用一或多個屬性,您可以僅指定 MIME 類型、URI 首碼、URI 配置,或指定這些項目的組合,以及表示所接受資料類型的其他項目。
+
+
+</p>
+ <p class="note"><strong>注意:</strong>若您不需要宣告 {@link android.net.Uri} 資料的有關詳情 (例如若您的應用行為顯示處理其他類型的「額外」資料,而非處理 URI),應僅指定 {@code android:mimeType} 屬性以宣告應用行為顯示處理的資料類型,例如 {@code text/plain} 或 {@code image/jpeg}。
+
+
+</p>
+</dd>
+ <dt>類別</dt>
+ <dd>提供對處理意圖的應用行為顯示進行特性描述的其他方式,通常與使用者的手勢或應用行為顯示的啟動位置有關。
+系統支援多種不同的類別,但大多數類別很少使用。
+然而依預設,所有隱含意圖都與 {@link android.content.Intent#CATEGORY_DEFAULT} 一併定義。
+
+ <p>請在意圖篩選器中使用 <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code &lt;category&gt;}</a> 元素指定此項目。
+</p></dd>
+</dl>
+
+<p>在意圖篩選器中,您可以宣告每個條件以及 <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter&gt;}</a> 元素中巢套的對應 XML 元素,以宣告應用行為顯示所接受的條件。
+
+</p>
+
+<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;data android:mimeType="image/*"/>
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p>傳入的每項意圖只會指定一項行為與一種資料類型,但是在每個 <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a> 中,可以宣告 <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> 與 <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code
+&lt;data&gt;}</a> 元素的多個執行個體。
+
+</p>
+
+<p>若兩個行為與資料配對在行為方面彼此排斥,您應建立單獨的意圖篩選器,以指定與哪些資料類型配對時可接受哪些行為。
+
+</p>
+
+<p>例如,假設您的應用行為顯示可處理 {@link
+android.content.Intent#ACTION_SEND} 與 {@link
+android.content.Intent#ACTION_SENDTO} 意圖的文字與影像。在此情況下,您必須針對兩個行為定義兩個單獨的意圖篩選器,因為 {@link
+android.content.Intent#ACTION_SENDTO} 意圖必須使用 {@link android.net.Uri} 資料指定接收者的地址 (使用 {@code send} 或 {@code sendto} URI 配置)。
+
+例如:</p>
+
+<pre>
+&lt;activity android:name="ShareActivity">
+ &lt;!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.SENDTO"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:scheme="sms" />
+ &lt;data android:scheme="smsto" />
+ &lt;/intent-filter>
+ &lt;!-- filter for sending text or images; accepts SEND action and text or image data -->
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.SEND"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:mimeType="image/*"/>
+ &lt;data android:mimeType="text/plain"/>
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p class="note"><strong>注意:</strong>若要接收隱含意圖,您必須在意圖篩選器中納入 {@link android.content.Intent#CATEGORY_DEFAULT} 類別。
+{@link
+android.app.Activity#startActivity startActivity()} 與 {@link
+android.app.Activity#startActivityForResult startActivityForResult()} 方法對所有意圖進行處理時,就像已宣告 {@link android.content.Intent#CATEGORY_DEFAULT} 類別一樣。
+若您在意圖篩選器中未宣告該類別,不會將任何隱含意圖解析為您的應用行為顯示。
+</p>
+
+<p>如需有關傳送及接收 {@link android.content.Intent#ACTION_SEND} 意圖 (執行社交共用行為) 的詳細資訊,請參閱有關<a href="{@docRoot}training/sharing/receive.html">接收其他應用程式的簡單資料</a>的課程。
+</p>
+
+
+<h2 id="HandleIntent">在應用行為顯示中處理意圖</h2>
+
+<p>若要確定您應用行為顯示中將採用的行為,您可以讀取用於啟動該應用行為顯示的 {@link
+android.content.Intent}。</p>
+
+<p>您的應用行為顯示啟動時,請呼叫 {@link android.app.Activity#getIntent()} 以擷取啟動該應用行為顯示的 {@link android.content.Intent}。
+在應用行為顯示的生命週期期間,您隨時可以執行該作業,但通常應在早期回呼 (例如 {@link android.app.Activity#onCreate onCreate()} 或 {@link android.app.Activity#onStart()}) 期間執行。
+
+</p>
+
+<p>例如:</p>
+
+<pre>
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.main);
+
+ // Get the intent that started this activity
+ Intent intent = getIntent();
+ Uri data = intent.getData();
+
+ // Figure out what to do based on the intent type
+ if (intent.getType().indexOf("image/") != -1) {
+ // Handle intents with image data ...
+ } else if (intent.getType().equals("text/plain")) {
+ // Handle intents with text ...
+ }
+}
+</pre>
+
+
+<h2 id="ReturnResult">傳回結果</h2>
+
+<p>若您希望將結果傳回至呼叫您意圖的應用行為顯示,只需呼叫 {@link
+android.app.Activity#setResult(int,Intent) setResult()} 以指定結果代碼及結果 {@link
+android.content.Intent} 即可。在您的操作已完成,且使用者應返回原始的應用行為顯示時,請呼叫 {@link android.app.Activity#finish()} 以關閉 (並終結) 您的應用行為顯示。
+例如:
+</p>
+
+<pre>
+// Create intent to deliver some kind of result data
+Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");
+setResult(Activity.RESULT_OK, result);
+finish();
+</pre>
+
+<p>您必須始終一併指定結果代碼與結果。結果通常是 {@link
+android.app.Activity#RESULT_OK} 或 {@link android.app.Activity#RESULT_CANCELED}。然後,您可以視需要為其他資料提供 {@link android.content.Intent}。
+</p>
+
+<p class="note"><strong>注意:</strong>依預設,會將結果設為 {@link
+android.app.Activity#RESULT_CANCELED}。因此,若使用者在完成行為之前以及在您設定結果之前按下 [後退] 按鈕<em></em>,原始應用行為顯示會收到「已取消」結果。
+
+</p>
+
+<p>若您只需傳回表示其中一種結果選項的整數,可將結果代碼設為大於 0 的任意值。
+若您使用結果代碼以提供整數,且無需納入 {@link android.content.Intent},可以呼叫 {@link
+android.app.Activity#setResult(int) setResult()},然後僅傳遞結果代碼。
+例如:</p>
+
+<pre>
+setResult(RESULT_COLOR_RED);
+finish();
+</pre>
+
+<p>在此情況下,可能只會有少數結果,因此結果代碼是本機定義的整數 (大於 0)。
+若您將結果傳回至您應用程式內的應用行為顯示,此功能會非常適用,因為接收結果的應用行為顯示可以參考公用常數,以確定結果代碼的值。
+
+</p>
+
+<p class="note"><strong>注意:</strong>無需檢查是否已使用 {@link
+android.app.Activity#startActivity startActivity()} 或 {@link
+android.app.Activity#startActivityForResult startActivityForResult()} 啟動您的應用行為顯示。
+若啟動應用行為顯示的意圖希望產生結果,只需呼叫 {@link
+android.app.Activity#setResult(int,Intent) setResult()} 即可。
+若原始應用行為已呼叫 {@link
+android.app.Activity#startActivityForResult startActivityForResult()},則系統將向其傳遞您提供給 {@link android.app.Activity#setResult(int,Intent) setResult()} 的結果;否則,結果將被忽略。
+
+</p>
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/zh-tw/training/basics/intents/index.jd b/docs/html-intl/intl/zh-tw/training/basics/intents/index.jd
new file mode 100644
index 0000000..70492f4
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/training/basics/intents/index.jd
@@ -0,0 +1,62 @@
+page.title=與其他應用程式互動
+page.tags=意圖,應用行為的顯示
+helpoutsWidget=true
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>相依性和先決條件</h2>
+<ul>
+ <li>了解應用行為顯示生命週期的基本知識 (請參閱<a href="{@docRoot}training/basics/activity-lifecycle/index.html">管理應用行為顯示生命週期</a>)
+</li>
+</ul>
+
+
+<h2>您也應該閱讀</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">共用簡單資料</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">共用檔案</a>
+ <li><a href="http://android-developers.blogspot.com/2009/11/integrating-application-with-intents.html">將應用程式與意圖整合 (部落格文章)</a>
+</li>
+ <li><a href="{@docRoot}guide/components/intents-filters.html">意圖和意圖篩選器</a>
+</li>
+</ul>
+
+</div>
+</div>
+
+<p>Android 應用程式通常具有多個<a href="{@docRoot}guide/components/activities.html">應用行為顯示</a>。每個應用行為顯示都會顯示使用者介面,使用者可藉此執行特定任務 (例如檢視地圖或拍照)。若要將使用者從一個應用行為顯示傳送至另一個應用行為顯示,您的應用程式必須使用 {@link
+android.content.Intent} 來定義應用程式執行作業的「意圖」。
+
+使用某方法 (例如 {@link
+android.app.Activity#startActivity startActivity()}) 將 {@link android.content.Intent} 傳遞至系統時,
+系統會使用 {@link
+android.content.Intent} 來識別並啟動相應的應用程式元件。若使用意圖,應用程式甚至可以藉此啟動獨立應用程式中包含的應用行為顯示。
+</p>
+
+<p>{@link android.content.Intent} 可以是<em>明確的</em>,以啟動特定元件
+(特定 {@link android.app.Activity} 執行個體),也可以是<em>隱含的</em>,以啟動可處理預期行為 (例如「拍照」) 的元件。
+</p>
+
+<p>本課程將為您展示如何使用 {@link android.content.Intent} 來執行與其他應用程式的某些基本互動,例如啟動其他應用程式、接收該應用程式的結果,以及讓您的應用程式能回應其他應用程式的意圖。
+
+</p>
+
+<h2>課程</h2>
+
+<dl>
+ <dt><b><a href="sending.html">將使用者傳送至其他應用程式</a></b></dt>
+ <dd>展示如何建立隱含意圖以啟動能執行行為的其他應用程式。
+</dd>
+ <dt><b><a href="result.html">從應用行為顯示取得結果</a></b></dt>
+ <dd>展示如何啟動其他應用行為顯示並接收應用行為顯示傳回的結果。</dd>
+ <dt><b><a href="filters.html">允許其他應用程式啟動您的應用行為顯示</a></b></dt>
+ <dd>展示如何透過定義對您的應用程式所接受的隱含意圖進行宣告的意圖篩選器,讓應用程式中的應用行為顯示可供其他應用程式使用。
+</dd>
+</dl>
+
diff --git a/docs/html-intl/intl/zh-tw/training/basics/intents/result.jd b/docs/html-intl/intl/zh-tw/training/basics/intents/result.jd
new file mode 100644
index 0000000..9fabe91
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/training/basics/intents/result.jd
@@ -0,0 +1,178 @@
+page.title=從應用行為顯示取得結果
+page.tags=意圖
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>本課程示範</h2>
+<ol>
+ <li><a href="#StartActivity">啟動應用行為顯示</a></li>
+ <li><a href="#ReceiveResult">接收結果</a></li>
+</ol>
+
+<h2>您也應該閱讀</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">共用簡單資料</a></li>
+ <li><a href="{@docRoot}training/secure-file-sharing/index.html">共用檔案</a>
+</ul>
+
+ </div>
+</div>
+
+<p>啟動其他應用行為顯示不必是單向作業。您也可以啟動其他應用行為顯示,然後接收傳回的結果。
+若要接收結果,請呼叫 {@link android.app.Activity#startActivityForResult
+startActivityForResult()} (而非 {@link android.app.Activity#startActivity
+startActivity()})。</p>
+
+<p>例如,您的應用程式可以啟動相機應用程式,然後接收所拍攝的相片作為結果。或者,您可以啟動人員應用程式 (以便讓使用者選取連絡人),然後接收作為結果的連絡人詳細資料。
+
+</p>
+
+<p>當然,必須將提供回應的應用行為顯示設計為傳回結果。執行時,該應用行為顯示會以其他 {@link android.content.Intent} 物件的形式傳送結果。
+您的應用行為顯示會在 {@link android.app.Activity#onActivityResult onActivityResult()} 回呼中接收該結果。
+</p>
+
+<p class="note"><strong>注意:</strong>呼叫 {@link android.app.Activity#startActivityForResult startActivityForResult()} 時,您可以使用明確或隱含的意圖。
+啟動您的其中一個應用行為顯示以接收結果時,您應使用明確的意圖,以確保收到預期結果。
+
+</p>
+
+
+<h2 id="StartActivity">啟動應用行為顯示</h2>
+
+<p>啟動應用行為顯示以接收結果時,您使用的 {@link android.content.Intent} 物件沒有任何特殊之處,但是您需要將附加整數引數傳遞至 {@link
+android.app.Activity#startActivityForResult startActivityForResult()} 方法。
+</p>
+
+<p>該整數引數是識別您要求的「要求代碼」。在您接收結果 {@link android.content.Intent} 時,回呼會提供同一要求代碼,以便您的應用程式可以正確識別結果並判斷如何處理結果。
+
+</p>
+
+<p>例如,以下展示了如何啟動應用行為顯示 (使用者可藉此挑選連絡人):</p>
+
+<pre>
+static final int PICK_CONTACT_REQUEST = 1; // The request code
+...
+private void pickContact() {
+ Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
+ pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
+ startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
+}
+</pre>
+
+
+<h2 id="ReceiveResult">接收結果</h2>
+
+<p>使用者處理隨後的應用行為顯示並返回時,系統會呼叫應用行為顯示的 {@link android.app.Activity#onActivityResult onActivityResult()} 方法。
+此方法包括三個引數:
+</p>
+
+<ul>
+ <li>您傳遞至 {@link
+android.app.Activity#startActivityForResult startActivityForResult()} 的要求代碼。</li>
+ <li>由第二個應用行為顯示指定的結果代碼。此代碼是 {@link
+android.app.Activity#RESULT_OK} (若操作成功) 或 {@link
+android.app.Activity#RESULT_CANCELED} (若因故使用者退出或操作失敗)。
+</li>
+ <li>攜帶結果資料的 {@link android.content.Intent}。</li>
+</ul>
+
+<p>例如,以下為您展示了如何處理「挑選連絡人」意圖的結果:</p>
+
+<pre>
+&#64;Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // Check which request we're responding to
+ if (requestCode == PICK_CONTACT_REQUEST) {
+ // Make sure the request was successful
+ if (resultCode == RESULT_OK) {
+ // The user picked a contact.
+ // The Intent's data Uri identifies which contact was selected.
+
+ // Do something with the contact here (bigger example below)
+ }
+ }
+}
+</pre>
+
+<p>在此範例中,由 Android 的連絡人或人員應用程式傳回的結果 {@link android.content.Intent} 可提供內容 {@link android.net.Uri} (能識別使用者所選取的連絡人)。
+
+</p>
+
+<p>若要成功處理結果,您必須了解結果 {@link android.content.Intent} 將採用的格式。
+若傳回結果的應用行為顯示是您的其中一個應用行為顯示,上述作業會非常簡單。
+Android 平台隨附的應用程式會針對特定結果資料提供您可以依賴的 API。
+例如,人員應用程式 (某些舊版上的連絡人應用程式) 會始終傳回含內容 URI (可識別選取的連絡人) 的結果,相機應用程式會在 {@code "data"} 額外項目中傳回 {@link android.graphics.Bitmap} (請參閱有關<a href="{@docRoot}training/camera/index.html">拍攝相片</a>的課程)。
+
+
+</p>
+
+
+<h4>額外說明:讀取連絡人資料</h4>
+
+<p>上述程式碼展示如何從人員應用程式取得結果,並未詳述如何實際讀取結果的資料,因為這需要進行更高級的
+<a href="{@docRoot}guide/topics/providers/content-providers.html">內容提供者</a>相關討論。
+
+但是,若您對此感到好奇,以下提供了另外一些程式碼,這些程式碼會展示如何查詢結果資料,以便取得所選連絡人的電話號碼:
+</p>
+
+<pre>
+&#64;Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // Check which request it is that we're responding to
+ if (requestCode == PICK_CONTACT_REQUEST) {
+ // Make sure the request was successful
+ if (resultCode == RESULT_OK) {
+ // Get the URI that points to the selected contact
+ Uri contactUri = data.getData();
+ // We only need the NUMBER column, because there will be only one row in the result
+ String[] projection = {Phone.NUMBER};
+
+ // Perform the query on the contact to get the NUMBER column
+ // We don't need a selection or sort order (there's only one result for the given URI)
+ // CAUTION: The query() method should be called from a separate thread to avoid blocking
+ // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
+ // Consider using {@link android.content.CursorLoader} to perform the query.
+ Cursor cursor = getContentResolver()
+ .query(contactUri, projection, null, null, null);
+ cursor.moveToFirst();
+
+ // Retrieve the phone number from the NUMBER column
+ int column = cursor.getColumnIndex(Phone.NUMBER);
+ String number = cursor.getString(column);
+
+ // Do something with the phone number...
+ }
+ }
+}
+</pre>
+
+<p class="note"><strong>注意:</strong>在 Android 2.3 (API 級別為 9) 版之前,若在 {@link android.provider.ContactsContract.Contacts Contacts Provider} (例如以上所示) 上執行查詢,需要您的應用程式宣告 {@link
+android.Manifest.permission#READ_CONTACTS} 權限 (請參閱<a href="{@docRoot}guide/topics/security/security.html">安全性與權限</a>)。
+
+但是,從 Android 2.3 版開始,在連絡人提供者傳回結果時,連絡人/人員應用程式會為您的應用程式授予讀取連絡人提供者的臨時權限。
+
+該臨時權限僅適用於要求的特定連絡人,因此除非您已宣告 {@link
+android.Manifest.permission#READ_CONTACTS} 權限,否則無法查詢並非由意圖的 {@link android.net.Uri} 指定的連絡人。
+
+</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/zh-tw/training/basics/intents/sending.jd b/docs/html-intl/intl/zh-tw/training/basics/intents/sending.jd
new file mode 100644
index 0000000..70e8316
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/training/basics/intents/sending.jd
@@ -0,0 +1,256 @@
+page.title=將使用者傳送至其他應用程式
+page.tags=意圖
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+<h2>本課程示範</h2>
+<ol>
+ <li><a href="#Build">建置隱含意圖</a></li>
+ <li><a href="#Verify">驗證存在接收意圖的應用程式</a></li>
+ <li><a href="#StartActivity">使用意圖啟動應用行為顯示</a></li>
+ <li><a href="#AppChooser">顯示應用程式選擇器</a></li>
+</ol>
+
+<h2>您也應該閱讀</h2>
+<ul>
+ <li><a href="{@docRoot}training/sharing/index.html">共用簡單資料</a></li>
+</ul>
+
+ </div>
+</div>
+
+<p>應用程式可以根據將要執行的「行為」,將使用者傳送至其他應用程式
+,這是 Android 最重要的功能之一。例如,若您希望在地圖上顯示應用程式中的企業地址,不必在應用程式中建置顯示地圖的應用行為顯示。
+
+您可以改為使用 {@link android.content.Intent} 建立檢視地址的要求。
+隨後,Android 系統會啟動能在地圖上顯示地址的應用程式。
+</p>
+
+<p>正如第一課<a href="{@docRoot}training/basics/firstapp/index.html">建置您的第一個應用程式</a>中所述,您必須使用意圖在您應用程式中的應用行為顯示之間進行導覽。您執行此作業時通常具有<em>明確意圖</em>,該意圖可定義您希望啟動的元件的確切類別名稱。
+
+
+但是,若您希望使用單獨的應用程式執行諸如「檢視地圖」等行為,則必須使用<em>隱含意圖</em>。
+</p>
+
+<p>本課程將為您展示如何針對特定行為建立隱含意圖,以及如何使用該意圖啟動在其他應用程式中執行該行為的應用行為顯示。
+</p>
+
+
+
+<h2 id="Build">建置隱含意圖</h2>
+
+<p>隱含意圖不會宣告要啟動元件的類別名稱,而是宣告要執行的行為。
+該行為將指定您希望執行的動作,例如<em>檢視</em>、<em>編輯</em>、<em>傳送</em>或<em>取得</em>項目。
+意圖通常還包括與行為關聯的資料,例如您希望檢視的地址或希望傳送的電子郵件。視您希望建立的意圖而定,該資料可能是 {@link android.net.Uri} 或其他多種資料類型的其中之一,意圖也可能完全不需要資料。
+
+
+</p>
+
+<p>若您的資料是 {@link android.net.Uri},可以使用簡單的 {@link
+android.content.Intent#Intent(String,Uri) Intent()} 建構函式來定義行為與資料。
+</p>
+
+<p>例如,以下範例將展示如何建立啟動電話的意圖 (使用 {@link
+android.net.Uri} 資料指定電話號碼):</p>
+
+<pre>
+Uri number = Uri.parse("tel:5551234");
+Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
+</pre>
+
+<p>您的應用程式透過呼叫 {@link android.app.Activity#startActivity
+startActivity()} 來呼叫該意圖時,電話應用程式會啟動對指定電話號碼的撥號。</p>
+
+<p>以下將展示其他一些意圖及其行為與 {@link android.net.Uri} 資料配對:
+</p>
+
+<ul>
+ <li>檢視地圖:
+<pre>
+// Map point based on address
+Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
+// Or map point based on latitude/longitude
+// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
+Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
+</pre>
+ </li>
+ <li>檢視網頁:
+<pre>
+Uri webpage = Uri.parse("http://www.android.com");
+Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
+</pre>
+ </li>
+</ul>
+
+<p>其他類型的隱含意圖需要「額外」資料提供其他資料類型 (例如字串)。
+您可以使用各種 {@link
+android.content.Intent#putExtra(String,String) putExtra()} 方法新增一或多項額外資料。</p>
+
+<p>依預設,系統會根據包括的 {@link android.net.Uri} 資料,判斷意圖所需的相應 MIME 類型。
+若您未將 {@link android.net.Uri} 包括在意圖中,通常應使用 {@link android.content.Intent#setType setType()} 指定意圖所關聯資料的類型。
+
+設定 MIME 類型會進一步指定哪些類型的應用行為顯示應接收意圖。
+</p>
+
+<p>以下展示的一些意圖將新增額外資料以指定所需行為:</p>
+
+<ul>
+ <li>傳送具有附件的電子郵件:
+<pre>
+Intent emailIntent = new Intent(Intent.ACTION_SEND);
+// The intent does not have a URI, so declare the "text/plain" MIME type
+emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
+emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients
+emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
+emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
+emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));
+// You can also attach multiple items by passing an ArrayList of Uris
+</pre>
+ </li>
+ <li>建立行事曆事件:
+<pre>
+Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
+Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);
+Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);
+calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
+calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
+calendarIntent.putExtra(Events.TITLE, "Ninja class");
+calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");
+</pre>
+<p class="note"><strong>注意:</strong>針對行事曆事件的這一意圖僅支援至少為 14 的 API 級別。
+</p>
+ </li>
+</ul>
+
+<p class="note"><strong>注意:</strong>請儘可能具體地定義 {@link
+android.content.Intent},這一點非常重要。例如,若您希望使用 {@link android.content.Intent#ACTION_VIEW} 意圖顯示影像,應將 MIME 類型指定為 {@code image/*}。
+
+如此可防止意圖觸發能「檢視」其他類型資料的應用程式 (例如地圖應用程式)。
+</p>
+
+
+
+<h2 id="Verify">驗證存在接收意圖的應用程式</h2>
+
+<p>雖然 Android 平台保證特定意圖將解析為內建應用程式 (例如電話、電子郵件或日曆應用程式) 的其中之一,但您應一律先納入驗證步驟,然後再呼叫意圖。
+
+</p>
+
+<p class="caution"><strong>注意:</strong>若您呼叫意圖,而裝置上不提供能處理該意圖的任何應用程式,
+則您的應用程式將當機。</p>
+
+<p>若要驗證存在可回應意圖的應用行為顯示,請呼叫 {@link
+android.content.pm.PackageManager#queryIntentActivities queryIntentActivities()} 以取得能處理 {@link android.content.Intent} 的應用行為顯示清單。
+若傳回的 {@link
+java.util.List} 非空,您可以安全使用意圖。例如:</p>
+
+<pre>
+PackageManager packageManager = {@link android.content.Context#getPackageManager()};
+List<ResolveInfo> activities = packageManager.queryIntentActivities(intent,
+ PackageManager.MATCH_DEFAULT_ONLY);
+boolean isIntentSafe = activities.size() > 0;
+</pre>
+
+<p>若 <code>isIntentSafe</code> 為 <code>true</code>,則至少有一個應用程式將回應意圖。
+若其為 <code>false</code>,則沒有任何應用程式能處理該意圖。</p>
+
+<p class="note"><strong>注意:</strong>對於使用該意圖的功能,若您需要在使用者嘗試使用該功能之前停用該功能,應在您的應用行為顯示第一次啟動時,執行這項檢查。
+
+若您知道能處理該意圖的特定應用程式,還可為使用者提供應用程式下載連結 (請參閱如何<a href="{@docRoot}distribute/tools/promote/linking.html">在 Google
+Play 上連結您的產品</a>)。
+</p>
+
+
+<h2 id="StartActivity">使用意圖啟動應用行為顯示</h2>
+
+<div class="figure" style="width:200px;margin-top:-10px">
+ <img src="{@docRoot}images/training/basics/intents-choice.png" alt="" />
+ <p class="img-caption"><strong>圖 1.</strong>選取對話方塊 (在多個應用程式可處理意圖時顯示) 的範例。
+</p>
+</div>
+
+<p>在您建立 {@link android.content.Intent} 並設定額外資訊後,請呼叫 {@link
+android.app.Activity#startActivity startActivity()} 將其傳送至系統。若系統識別出有多個應用行為顯示可以處理意圖,會顯示對話方塊,供使用者選取要使用的應用程式,如圖 1 所示。
+
+若只有一個應用行為顯示可以處理該意圖,系統會立即啟動該應用行為顯示。
+</p>
+
+<pre>
+startActivity(intent);
+</pre>
+
+<p>以下所示的完整範例將展示如何建立檢視地圖的意圖、驗證存在處理該意圖的應用程式,然後啟動該應用程式:
+</p>
+
+<pre>
+// Build the intent
+Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
+Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
+
+// Verify it resolves
+PackageManager packageManager = {@link android.content.Context#getPackageManager()};
+List&lt;ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
+boolean isIntentSafe = activities.size() > 0;
+
+// Start an activity if it's safe
+if (isIntentSafe) {
+ startActivity(mapIntent);
+}
+</pre>
+
+
+
+<h2 id="AppChooser">顯示應用程式選擇器</h2>
+
+<div class="figure" style="width:200px;margin-top:-10px">
+ <img src="{@docRoot}images/training/basics/intent-chooser.png" alt="" />
+ <p class="img-caption"><strong>圖 2.</strong>選擇器對話方塊。</p>
+</div>
+
+<p>請注意,若您將 {@link android.content.Intent} 傳遞至 {@link
+android.app.Activity#startActivity startActivity()} 以啟動應用行為顯示,且有多個應用程式回應該意圖,則使用者可以選取依預設要使用的應用程式 (透過選取對話方塊底部的核取方塊,請參閱圖 1)。
+
+若在執行行為時使用者通常希望每次使用同一應用程式,例如開啟網頁 (使用者可能只使用一個網頁瀏覽器) 或拍攝相片 (使用者可能更喜歡使用一個相機),則此功能非常有用。
+
+</p>
+
+<p>但是,若有多個應用程式可以處理要執行的行為,且使用者可能更希望每次使用不同的應用程式 (例如對於「共用」行為,使用者可能會透過多個應用程式來共用項目),您應明確顯示選擇器對話方塊,如圖 2 所示。
+
+
+選擇器對話方塊會強制使用者選取行為每次使用的應用程式 (使用者無法選取行為的預設應用程式)。
+
+</p>
+
+<p>若要顯示選擇器,請使用 {@link
+android.content.Intent#createChooser createChooser()} 建立 {@link android.content.Intent},並將其傳遞至 {@link
+android.app.Activity#startActivity startActivity()}。例如:</p>
+
+<pre>
+Intent intent = 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 chooser
+Intent chooser = Intent.createChooser(intent, title);
+
+// Verify the intent will resolve to at least one activity
+if (intent.resolveActivity(getPackageManager()) != null) {
+ startActivity(chooser);
+}
+</pre>
+
+<p>以上範例會顯示對話方塊 (將回應意圖的應用程式清單傳遞至 {@link
+android.content.Intent#createChooser createChooser()} 方法),並使用提供的文字作為對話方塊的標題。
+</p>
+
+
+
diff --git a/docs/html/design/design_toc.cs b/docs/html/design/design_toc.cs
index 85569ef..477eb23 100644
--- a/docs/html/design/design_toc.cs
+++ b/docs/html/design/design_toc.cs
@@ -3,13 +3,29 @@
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot ?>design/get-started/creative-vision.html">Creative Vision</a></div>
<ul>
- <li><a href="<?cs var:toroot ?>design/get-started/principles.html">Design Principles</a></li>
+ <li><a href="<?cs var:toroot ?>design/get-started/principles.html"
+ es-lang="Principios de diseño para Android"
+ ja-lang="Android デザイン指針"
+ ko-lang="Android 디자인 원칙"
+ pt-br-lang="Princípios de projeto para Android"
+ ru-lang="Принципы проектирования Android"
+ zh-cn-lang="Android 设计原则"
+ zh-tw-lang="Android 設計原則">
+ Design Principles</a></li>
<li><a href="<?cs var:toroot ?>design/patterns/new.html">New in Android</a></li>
</ul>
</li>
<li class="nav-section">
- <div class="nav-section-header empty"><a href="<?cs var:toroot ?>design/material/index.html">Material for Android</a></div>
+ <div class="nav-section-header empty"><a href="<?cs var:toroot ?>design/material/index.html"
+ es-lang="Material Design"
+ ja-lang="マテリアル デザイン"
+ ko-lang="머티어리얼 디자인"
+ pt-br-lang="Material Design"
+ ru-lang="Material Design"
+ zh-cn-lang="材料设计"
+ zh-tw-lang="材料設計">
+ Material for Android</a></div>
</li>
<li class="nav-section">
@@ -47,12 +63,39 @@
<ul>
<li><a href="<?cs var:toroot ?>design/style/devices-displays.html">Devices and Displays</a></li>
<li><a href="<?cs var:toroot ?>design/patterns/app-structure.html">App Structure</a></li>
- <li><a href="<?cs var:toroot ?>design/patterns/navigation.html">Navigation</a></li>
- <li><a href="<?cs var:toroot ?>design/patterns/notifications.html">Notifications</a></li>
+ <li><a href="<?cs var:toroot ?>design/patterns/navigation.html"
+ es-lang="Navegación con los botones Back y Up"
+ ja-lang="Back と Up を使用したナビゲーション"
+ ko-lang="뒤로 및 위로 탐색 기능이 포함된 탐색"
+ pt-br-lang="Navegação com Voltar e Para cima"
+ ru-lang="Навигация с помощью кнопок \"Назад\" и \"Вверх\""
+ zh-cn-lang="使用返回和向上导航"
+ zh-tw-lang="使用 [返回] 及 [上一層] 導覽">
+ Navigation</a></li>
+
+ <li><a href="<?cs var:toroot ?>design/patterns/notifications.html"
+ es-lang="Notificaciones"
+ ja-lang="通知"
+ ko-lang="알림"
+ pt-br-lang="Notificações"
+ ru-lang="Уведомления"
+ zh-cn-lang="通知"
+ zh-tw-lang="通知">
+ Notifications</a></li>
<li><a href="<?cs var:toroot ?>design/patterns/widgets.html">Widgets</a></li>
<li><a href="<?cs var:toroot ?>design/patterns/swipe-views.html">Swipe Views</a></li>
<li><a href="<?cs var:toroot ?>design/patterns/fullscreen.html">Full Screen</a></li>
- <li><a href="<?cs var:toroot ?>design/patterns/confirming-acknowledging.html">Confirming &amp; Acknowledging</a></li>
+
+ <li><a href="<?cs var:toroot ?>design/patterns/confirming-acknowledging.html"
+ es-lang="Confirmación y reconocimiento"
+ ja-lang="確認と通知"
+ ko-lang="확인 및 승인하기"
+ pt-br-lang="Confirmação e reconhecimento"
+ ru-lang="Подтверждение и уведомление"
+ zh-cn-lang="确认和确知"
+ zh-tw-lang="確認及確認完成">
+ Confirming &amp; Acknowledging</a></li>
+
<li><a href="<?cs var:toroot ?>design/patterns/pure-android.html">Pure Android</a></li>
<li><a href="<?cs var:toroot ?>design/patterns/compatibility.html">Compatibility</a></li>
<li><a href="<?cs var:toroot ?>design/patterns/accessibility.html">Accessibility</a></li>
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index b06da56..63eee96 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -549,6 +549,22 @@ is not related to the screen orientation.</p>
which indicates whether the screen is long.</p>
</td>
</tr>
+ <tr id="ScreenRoundQualifier">
+ <td>Round screen</td>
+ <td>
+ <code>round</code><br/>
+ <code>notround</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code round}: Round screens, such as a round wearable device</li>
+ <li>{@code notround}: Rectangular screens, such as phones or tablets</li>
+ </ul>
+ <p><em>Added in API level 23.</em></p>
+ <p>Also see the {@link android.content.res.Configuration#isScreenRound()} configuration
+method, which indicates whether the screen is round.</p>
+ </td>
+ </tr>
<tr id="OrientationQualifier">
<td>Screen orientation</td>
<td>
diff --git a/docs/html/guide/topics/security/permissions.jd b/docs/html/guide/topics/security/permissions.jd
index 6f919da..cfab3c9 100644
--- a/docs/html/guide/topics/security/permissions.jd
+++ b/docs/html/guide/topics/security/permissions.jd
@@ -52,9 +52,7 @@ must explicitly share resources and data. They do this by declaring the
<em>permissions</em> they need for additional capabilities not provided by
the basic sandbox. Applications statically declare the permissions they
require, and the Android system prompts the user for consent at the time the
-application is installed. Android has no mechanism for granting permissions
-dynamically (at run-time) because it complicates the user experience to the
-detriment of security.</p>
+application is installed.</p>
<p>The application sandbox does not depend on the technology used to build
an application. In particular the Dalvik VM is not a security boundary, and
diff --git a/docs/html/guide/topics/ui/actionbar.jd b/docs/html/guide/topics/ui/actionbar.jd
index d972c47..b2f98ad 100644
--- a/docs/html/guide/topics/ui/actionbar.jd
+++ b/docs/html/guide/topics/ui/actionbar.jd
@@ -907,11 +907,7 @@ to ensure the best fit in the action bar.</p>
<p>To get started, your layout must include a {@link android.view.ViewGroup} in which you place
each {@link android.app.Fragment} associated with a tab. Be sure the {@link android.view.ViewGroup}
has a resource ID so you can reference it from your code and swap the tabs within it.
-Alternatively, if the tab content will fill the activity layout, then your activity doesn't need a
-layout at all (you don't even need to call {@link android.app.Activity#setContentView
-setContentView()}). Instead, you can place each fragment in the default root view, which you can
-refer to with the {@code android.R.id.content} ID.</p>
-
+</p>
<p>Once you determine where the fragments appear in the layout, the basic procedure to add tabs
is:</p>
diff --git a/docs/html/images/tools/eclipse-notepad-pre-import--structure.png b/docs/html/images/tools/eclipse-notepad-pre-import--structure.png
new file mode 100644
index 0000000..b9c3814
--- /dev/null
+++ b/docs/html/images/tools/eclipse-notepad-pre-import--structure.png
Binary files differ
diff --git a/docs/html/images/tools/studio-globe-icon.png b/docs/html/images/tools/studio-globe-icon.png
new file mode 100644
index 0000000..0701dd2
--- /dev/null
+++ b/docs/html/images/tools/studio-globe-icon.png
Binary files differ
diff --git a/docs/html/images/tools/studio-import-destination-dir.png b/docs/html/images/tools/studio-import-destination-dir.png
new file mode 100644
index 0000000..d1c6c70
--- /dev/null
+++ b/docs/html/images/tools/studio-import-destination-dir.png
Binary files differ
diff --git a/docs/html/images/tools/studio-import-options.png b/docs/html/images/tools/studio-import-options.png
new file mode 100644
index 0000000..f14eca0
--- /dev/null
+++ b/docs/html/images/tools/studio-import-options.png
Binary files differ
diff --git a/docs/html/images/tools/studio-import-project-structure-android.png b/docs/html/images/tools/studio-import-project-structure-android.png
new file mode 100644
index 0000000..4cd7186
--- /dev/null
+++ b/docs/html/images/tools/studio-import-project-structure-android.png
Binary files differ
diff --git a/docs/html/images/tools/studio-import-project-structure-project.png b/docs/html/images/tools/studio-import-project-structure-project.png
new file mode 100644
index 0000000..c7ffda8
--- /dev/null
+++ b/docs/html/images/tools/studio-import-project-structure-project.png
Binary files differ
diff --git a/docs/html/images/tools/studio-import-summary.png b/docs/html/images/tools/studio-import-summary.png
new file mode 100644
index 0000000..a85e339
--- /dev/null
+++ b/docs/html/images/tools/studio-import-summary.png
Binary files differ
diff --git a/docs/html/images/tools/studio-select-project-forimport.png b/docs/html/images/tools/studio-select-project-forimport.png
new file mode 100644
index 0000000..c6a3599
--- /dev/null
+++ b/docs/html/images/tools/studio-select-project-forimport.png
Binary files differ
diff --git a/docs/html/images/tools/studio-setup-wizard.png b/docs/html/images/tools/studio-setup-wizard.png
deleted file mode 100644
index ccd92d3..0000000
--- a/docs/html/images/tools/studio-setup-wizard.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/preview/preview_toc.cs b/docs/html/preview/preview_toc.cs
index d0aa55f..6ef75a5 100644
--- a/docs/html/preview/preview_toc.cs
+++ b/docs/html/preview/preview_toc.cs
@@ -1,10 +1,18 @@
<ul id="nav">
<li class="nav-section">
- <div class="nav-section-header empty"><a href="<?cs var:toroot ?>preview/overview.html">
- Program Overview</a></div>
+ <div class="nav-section-header empty"><a href="<?cs var:toroot ?>preview/overview.html"
+ es-lang="Información general del programa"
+ ja-lang="プログラム概要"
+ ko-lang="프로그램 개요"
+ pt-br-lang="Visão geral do programa"
+ ru-lang="Обзор программы"
+ zh-cn-lang="计划概览"
+ zh-tw-lang="程式總覽">Program Overview
+ </a></div>
</li>
+
<li class="nav-section">
<div class="nav-section-header empty"><a href="<?cs var:toroot ?>preview/download.html">
Downloads</a></div>
@@ -25,11 +33,25 @@
</li>
<li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>preview/api-overview.html">
- API Overview</a></div>
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>preview/api-overview.html"
+ es-lang="Información general de la API"
+ ja-lang="API の概要"
+ ko-lang="API 개요"
+ pt-br-lang="Visão geral da API"
+ ru-lang="Обзор API-интерфейсов"
+ zh-cn-lang="API 概览"
+ zh-tw-lang="API 總覽">API Overview
+ </a></div>
<ul>
- <li><a href="<?cs var:toroot ?>preview/features/runtime-permissions.html">
- Permissions</a></li>
+ <li><a href="<?cs var:toroot ?>preview/features/runtime-permissions.html"
+ es-lang="Permisos"
+ ja-lang="パーミッション"
+ ko-lang="권한"
+ pt-br-lang="Permissões"
+ ru-lang="Разрешения"
+ zh-cn-lang="权限"
+ zh-tw-lang="權限">Permissions
+ </a></li>
<li><a href="<?cs var:toroot ?>preview/features/app-linking.html">
App Links</a></li>
<li><a href="<?cs var:toroot ?>preview/backup/index.html">
@@ -38,8 +60,15 @@
</li>
<li class="nav-section">
- <div class="nav-section-header empty"><a href="<?cs var:toroot ?>preview/behavior-changes.html">
- Behavior Changes</a></div>
+ <div class="nav-section-header empty"><a href="<?cs var:toroot ?>preview/behavior-changes.html"
+ es-lang="Cambios en los comportamientos"
+ ja-lang="動作の変更点"
+ ko-lang="동작 변경"
+ pt-br-lang="Mudanças de comportamento"
+ ru-lang="Изменения в работе"
+ zh-cn-lang="行为变更"
+ zh-tw-lang="行為變更">Behavior Changes
+ </a></div>
</li>
<li class="nav-section">
<div class="nav-section-header empty"><a href="<?cs var:toroot ?>preview/samples.html">
diff --git a/docs/html/sdk/installing/installing-adt.jd b/docs/html/sdk/installing/installing-adt.jd
index 5559d1a..b89c068 100644
--- a/docs/html/sdk/installing/installing-adt.jd
+++ b/docs/html/sdk/installing/installing-adt.jd
@@ -7,6 +7,14 @@ adt.zip.checksum=f64b7e50c84799f41c642218c35f1bbe
@jd:body
+<p class="caution">
+ <strong>Important:</strong> Support for the Android Developer Tools (ADT) in Eclipse is ending,
+ per our <a href=
+ "http://android-developers.blogspot.com/2015/06/an-update-on-eclipse-android-developer.html"
+ class="external-link">announcement</a>. You should migrate your app development projects to
+ Android Studio as soon as possible. For more information on transitioning to Android Studio, see
+ <a href="{@docRoot}sdk/installing/migrate.html">Migrating to Android Studio</a>.
+</p>
<p>Android offers a custom plugin for the Eclipse IDE, called Android
Development Tools (ADT). This plugin provides a powerful, integrated
@@ -15,15 +23,6 @@ of Eclipse to let you quickly set up new Android projects, build an app
UI, debug your app, and export signed (or unsigned) app packages (APKs) for distribution.
</p>
-<p class="note"><strong>Note:</strong>
-If you have been using Eclipse with ADT, be aware that <a
-href="{@docRoot}tools/studio/index.html">Android Studio</a> is now the official IDE
-for Android, so you should migrate to Android Studio to receive all the
-latest IDE updates. For help moving projects,
-see <a href="/sdk/installing/migrate.html">Migrating to Android
-Studio</a>.</p>
-
-
<p>You should install the ADT plugin
only if you already have an Eclipse installation that you want to continue using.
Your existing Eclipse installation must meet these requirements:</p>
diff --git a/docs/html/sdk/installing/migrate.jd b/docs/html/sdk/installing/migrate.jd
index 345e89a..6dedad6 100644
--- a/docs/html/sdk/installing/migrate.jd
+++ b/docs/html/sdk/installing/migrate.jd
@@ -4,53 +4,264 @@ page.title=Migrating to Android Studio
<div id="qv-wrapper">
<div id="qv">
+
+
+<h2>In this document</h2>
+<ol>
+ <li><a href="#overview">Migration Overview</a></li>
+ <li><a href="#prerequisites">Migration Prerequisites</a></li>
+ <li><a href="#migrate">Importing Projects to Android Studio</a></li>
+ <li><a href="#post-migration">Validating imported projects</a></li>
+</ol>
+
+
<h2>See also</h2>
<ul>
+ <li><a href="{@docRoot}tools/studio/eclipse-transition-guide.html">
+ Transition Guide for Eclipse ADT</a></li>
<li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA"
- class="external-link">IntelliJ FAQ on migrating to IntelliJ IDEA</a></li>
- <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/Working+in+Eclipse+Compatibility+Mode" class="external-link"
- >Eclipse Compatibility Mode</a></li>
- <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA" class="external-link"
- >FAQ on Migrating</a></li>
+ class="external-link">IntelliJ FAQ on migrating to IntelliJ IDEA</a></li>
+ <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/IntelliJ+IDEA+for+Eclipse+Users"
+ class="external-link">IntelliJ IDEA for Eclipse users</a></li>
+ <li><a href="{@docRoot}tools/studio/index.html">Android Studio Overview</a></li>
</ul>
</div>
</div>
-<p>If you have been using <a href="{@docRoot}tools/help/adt.html">Eclipse with ADT</a>, be aware
-that <a href="{@docRoot}tools/studio/index.html">Android Studio</a> is now the official IDE for
-Android, so you should migrate to Android Studio to receive all the latest IDE updates.</p>
+<p>Migrating from Eclipse ADT to Android Studio requires adapting to a new project structure,
+build system, and IDE functionality. To simplify the migration process, Android Studio provides an
+import tool so you can quickly transition your Eclipse ADT workspaces and Ant build scripts to
+Android Studio projects and <a href="http://www.gradle.org">Gradle</a>-based build files.</p>
-<p>To migrate existing Android projects, simply import them using Android Studio:</p>
+<p>This document provides an overview of the migration process and walks you
+through a sample import procedure. For more information about Android Studio features and the
+Gradle-based build system, see <a href="{@docRoot}tools/studio/index.html">Android Studio Overview</a>
+and <a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a>.</p>
-<ol>
- <li>In Android Studio, from the main menu or the <strong>Welcome to Android Studio</strong> page,
- choose <strong>File &gt; Import Project</strong>.</li>
- <li> Select the Eclipse root project directory</strong> and click <strong>OK</strong>.
- <p class="note"><strong>Note:</strong> The Eclipse root directory must contain the
- <code>AndroidManifest.xml</code> file. Also, the root directory must contain either the
- <code>.project</code> and <strong>.classpath</strong> files from Eclipse or the
- <code>res/</code> and <code>src/</code> directories.</p>
+
+
+<h2 id="overview">Migration Overview </h2>
+<p>Migrating from Eclipse to Android Studio requires that you change the structure of your
+development projects, move to a new build system, and use a new user interface. Here are some of
+the key changes you should be aware of as you prepare to migrate to Android Studio:</p>
+<ul>
+ <li><strong>Project files</strong>
+ <p>Android Studio uses a different project structure. Each Eclipse ADT
+ project is called a module in Android Studio. Each instance of Android
+ Studio contains a project with one or more app modules. For more information see,
+ <a href="{@docRoot}tools/studio/eclipse-transition-guide.html#project-structure">Project
+ Structure</a>.</p></li>
+
+ <li><strong>Manifest settings</strong>
+ <p>Several elements in the <code>AndroidManifest.xml</code> file are now properties in the
+ <code>defaultConfig</code> and <code>productFlavors</code> blocks in the
+ <code>build.gradle</code> file. These elements are still valid manifest entries and may
+ appear in manifests from older projects, imported projects, dependencies, and libraries. For
+ more information see,
+ <a href="{@docRoot}tools/studio/eclipse-transition-guide.html#manifest-settings">Manifest
+ Settings</a>.</p></li>
+
+ <li><strong>Dependencies</strong>
+ <p>Library dependencies are handled differently in Android Studio, using Gradle dependency
+ declarations and Maven dependencies for well-known local source and binary libraries with
+ Maven coordinates. For more information see,
+ <a href="{@docRoot}tools/studio/eclipse-transition-guide.html#dependencies">Dependencies</a></p>
+ </li>
+
+ <li><strong>Test code</strong>
+ <p>With Eclipse ADT, test code is written in separate projects and integrated through the
+ <code>&lt;instrumentation&gt;</code> element in your manifest file. Android Studio provides a
+ <code>AndroidTest</code> folder within your project so you can easily add and maintain your test
+ code within the same project view. JUnit tests can also be configured to run locally to reduce
+ testing cycles.</p></li>
+
+ <li><strong>Gradle-based build system</strong>
+ <p>In place of XML-based Ant build files, Android Studio supports Gradle build files, which
+ use the Gradle Domain Specific Language (DSL) for ease of extensibility and customization.
+ The Android Studio build system also supports
+ <a href="{@docRoot}tools/building/configuring-gradle.html#workBuildVariants"> build variants</a>,
+ which are combinations of <code>productFlavor</code> and <code>buildTypes</code>, to customize
+ your build outputs.</p></li>
+
+ <li><strong>User interface</strong>
+ <p>Android Studio provides an intuitive interface and menu options based on the
+ <a class="external-link" href="https://www.jetbrains.com/idea/" target="_blank">IntelliJ IDEA</a>
+ IDE. To become familiar with the IDE basics, such as navigation, code completion, and keyboard
+ shortcuts, see
+ <a class="external-link" href="https://www.jetbrains.com/idea/help/intellij-idea-quick-start-guide.html"
+ target="_blank">IntelliJ IDEA Quick Start Guide</a>.</p></li>
+
+ <li><strong>Developer tools versioning</strong>
+ <p>Android Studio updates independently of the Gradle-based build system so different build
+ settings can be applied across different versions of command line, Android Studio, and
+ continuous integration builds. For more information, see
+ <a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a>.</p>
+ </li>
+</ul>
+
+
+
+
+<h2 id="prerequisites">Migration Prerequisites</h2>
+<p>Before migrating your Eclipse ADT app to Android Studio, review the following steps to make
+sure your project is ready for conversion, and verify you have the tool configuration you need in
+Android Studio:</p>
+
+<ul>
+ <li>In Eclipse ADT:
+ <ul>
+ <li>Make sure the Eclipse ADT root directory contains the <code>AndroidManifest.xml</code>
+ file. Also, the root directory must contain either the <code>.project</code> and
+ <code>.classpath</code> files from Eclipse or the <code>res/</code> and <code>src/</code>
+ directories.</li>
+ <li>Build your project to ensure your latest workspace and project updates are saved and
+ included in the import.</li>
+ <li>Comment out any references to Eclipse ADT workspace library files in the
+ <code>project.properties</code> or <code>.classpath</code> files for import. You can
+ add these references in the <code>build.gradle</code> file after the import. For more
+ information, see
+ <a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a>.</li>
+ <li>It may be useful to record your workspace directory, path variables, and any actual path
+ maps that could be used to specify any unresolved relative paths, path variables, and
+ linked resource references. Android Studio allows you to manually specify any unresolved
+ paths during the import process.</li>
+ </ul>
+ </li>
+ <li>In Android Studio:
+ <ul>
+ <li>Make a note of any third-party Eclipse ADT plugins in use and check for equivalent features
+ in Android Studio or search for a compatible plugin in the
+ <a href="https://plugins.jetbrains.com/?androidstudio" class="external-link">IntelliJ Android
+ Studio Plugins</a> repository. Use the <strong>File &gt; Settings &gt; Plugins</strong> menu
+ option to manage plugins in Android Studio. Android Studio does not migrate any third-party
+ Eclipse ADT plugins.</li>
+ <li>If you plan to run Android Studio behind a firewall, be sure to set the proxy settings for
+ Android Studio and the SDK Manager. Android Studio requires an internet connection for
+ Setup Wizard synchronization, 3rd-party library access, access to remote repositories,
+ <a href="http://www.gradle.org" class="external-link">Gradle</a>
+ initialization and synchronization, and Android Studio version updates. For more information,
+ see <a href="{@docRoot}tools/studio/index.html#proxy">Proxy Settings</a>.</li>
+ <li>Use the <strong>File &gt; Settings &gt; System Settings</strong> menu option to verify the
+ current version and, if necessary, update Android Studio to the latest version from the
+ stable channel. To install Android Studio, please visit the
+ <a href="{@docRoot}sdk/index.html">Android Studio download page</a>.</li>
+ </ul>
</li>
- <li>Follow the steps in the import wizard. </li>
+ </ul>
+
+
+
+<h2 id="migrate">Importing Projects to Android Studio</h2>
+<p>Android Studio provides a function for importing Eclipse ADT projects, which creates a new
+Android Studio project and app modules based on your current
+Eclipse ADT workspace and projects. No changes are made to your Eclipse project files. The Eclipse
+ADT workspace becomes a new Android Studio project, and each Eclipse ADT project within the workspace
+becomes a new Android Studio module. Each instance of Android Studio contains a project with one or
+more app modules.</p>
+
+<p>After selecting an Eclipse ADT project to import, Android Studio creates the Android
+Studio project structure and app modules, generates the new Gradle-based build files and settings,
+and configures the required dependencies. The import options also allow you to enter your workspace
+directory and any actual path maps to handle any unresolved relative paths, path variables, and
+linked resource references.</p>
+
+<p>Depending on the structure of your Eclipse ADT development project, you should select specific
+files for importing:</p>
+<ul>
+<li>For workspaces with multiple projects, select the project folder for each Eclipse ADT
+ project individually to import the projects into the same Android Studio project. Android
+ Studio combines the Eclipse ADT projects into a single Android Studio project with different app
+ modules for each imported project.</li>
+
+<li>For Eclipse ADT projects with separate test projects, select the test project folder for
+ import. Android Studio imports the test project and then follows the dependency chain to import
+ the source project and any project dependencies.</li>
+
+ <li>If Eclipse ADT projects share dependencies within the same workspace, import each
+ project individually into Android Studio. Android Studio maintains the shared dependencies
+ across the newly created modules as part of the import process.</li>
+</ul>
+
+<p>To import a project to Android Studio:</p>
+
+<ol>
+ <li>Start Android Studio and close any open Android Studio projects.</li>
+ <li>From the Android Studio menu select <strong>File &gt; New &gt; Import Project</strong>.
+ <p>Alternatively, from the <em>Welcome</em> screen, select <strong>Import project
+ (Eclipse ADT, Gradle, etc.)</strong>.</p></li>
+ <li>Select the Eclipse ADT project folder with the <code>AndroidManifest.xml</code> file
+ and click <strong>Ok</strong>.
+ <p> <img src="{@docRoot}images/tools/studio-select-project-forimport.png" alt="" /></p>
+ </li>
+ <li>Select the destination folder and click <strong>Next</strong>.
+ <p> <img src="{@docRoot}images/tools/studio-import-destination-dir.png" alt="" /></p></li>
+ <li>Select the import options and click <strong>Finish</strong>.
+ <p>The import process prompts to migrate any library and project dependencies to Android Studio,
+ and add the dependency declarations to the <code>build.gradle</code> file. The import process
+ also replaces any well-known source libraries, binary libraries, and JAR files that have known
+ Maven coordinates with Maven dependencies, so you no longer need to maintain these dependencies
+ manually. The import options also allow you to enter your workspace directory and any actual
+ path maps to handle any unresolved relative paths, path variables, and linked resource
+ references.</p>
+ <p> <img src="{@docRoot}images/tools/studio-import-options.png" alt="" /></p></li>
+
+ <li>Android Studio imports the app and displays the project import summary. Review the summary
+ for details about the project restructuring and the import process.
+ <p> <img src="{@docRoot}images/tools/studio-import-summary.png"/></p>
+ </li>
</ol>
-<p>Android Studio imports the current dependencies, downloads libraries, and
-creates an Android Studio project with the imported Eclipse project as the main module. Android
-Studio also creates the required Gradle build files. </p>
+<p>After importing the project from Eclipse ADT to the new Android Studio project and module
+structure, each app module folder in Android Studio contains the complete source set for that
+module, including the {@code src/main} and {@code src/androidTest} directories, resources, build
+file, and Android manifest. Before starting app development, you should resolve any issues shown in
+the project import summary to make sure the project re-structuring and import process completed
+properly.</p>
+
+
+
+<h3 id="post-migration">Validating imported projects</h3>
+<p>After completing the import process, use the Android Studio <strong>Build</strong> and
+<strong>Run</strong> menu options to build your project and verify the output. If your project
+is not building properly, check the following settings:</p>
+
+<ul>
+<ul>
+ <li>Use the <strong>Android SDK</strong> button in Android Studio to launch the <a href=
+ "{@docRoot}tools/help/sdk-manager.html">SDK Manager</a> and verify the installed versions of SDK
+ tools, build tools, and platform match the settings for your Eclipse ADT project. Android Studio
+ inherits the SDK Manager and JDK settings from your imported Eclipse project.
+ </li>
+ <li>Use the <strong>File &gt; Project Structure</strong> menu option to verify additional
+ Android Studio settings:
+ <ul>
+ <li>Under <em>SDK Location</em> verify Android Studio has access to the correct SDK and
+ JDK locations and versions. </li>
+ <li>Under <em>Project</em> verify the Gradle version, Android Plugin version, and related
+ repositories.</li>
+ <li>Under <em>Modules</em> verify the app and module settings, such as signing configuration
+ and library dependencies. </li>
+ </ul>
+ </li>
+ <li>If your project depends on another project, make sure that dependency is defined properly in
+ the <code>build.gradle</code> file in the app module folder.</li>
+</ul>
+
-<p>The import process replaces any JAR files and libraries with Gradle dependencies, and replaces
-source libraries and binary libraries with Maven dependencies, so you no longer need to maintain
-these files manually.</p>
+<p>If there still are unexpected issues when building and running your project in Android
+Studio after you have checked these settings, consider modifying the Eclipse ADT project and
+re-starting the import process. Importing an Eclipse ADT project to Android Studio creates a new
+Android Studio project and does not impact the existing Eclipse ADT project. </p>
- <p class="note"><strong>Note:</strong> If there are references to Eclipse workspace library files,
- comment them out in the <code>project.properties</code> or <code>.classpath</code> files
- that you imported from the Eclipse project. You can then add these files in the
- <code>build.gradle</code> file. See
- <a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a>. </p>
-<p>For more help getting started with Android Studio and the IntelliJ user experience,
-<a href="{@docRoot}tools/studio/index.html">learn more about Android Studio</a> and
-read <a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA"
- class="external-link">FAQ on Migrating to IntelliJ IDEA</a>.</p>
+<p>To get started using Android Studio, review the
+<a href="{@docRoot}tools/studio/index.html">Android Studio</a> features and
+<a href="http://www.gradle.org">Gradle</a>-based build system to become familiar with the new
+project and module structure, flexible build settings, and other advanced Android development
+capabilities. For a comparison of Eclipse ADT and Android Studio features and usage, see
+<a href="{@docRoot}tools/studio/eclipse-transition-guide.html">Transitioning to Android Studio from
+Eclipse</a>. For specific Android Studio how-to documentation, see the pages in the
+<a href="{@docRoot}tools/workflow/index.html">Workflow</a> section.
+</p>
diff --git a/docs/html/sdk/installing/studio-tips.jd b/docs/html/sdk/installing/studio-tips.jd
index 4e732f0..7d37b1d 100644
--- a/docs/html/sdk/installing/studio-tips.jd
+++ b/docs/html/sdk/installing/studio-tips.jd
@@ -4,9 +4,16 @@ page.title=Android Studio Tips and Tricks
<div id="qv-wrapper">
<div id="qv">
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#productivity-features">Productivity Shortcuts</a></li>
+ <li><a href="#intellij">Working with IntelliJ</a></li>
+ <li><a href="#key-commands">Key Commands</a></li>
+ </ol>
+
<h2>See also</h2>
<ol>
- <li><a href="{@docRoot}tools/sdk/index.html">Download Android Studio</a></li>
+ <li><a href="{@docRoot}sdk/index.html">Download Android Studio</a></li>
<li><a href="http://wiki.jetbrains.net/intellij/Android">IntelliJ IDEA Android Tutorials</a></li>
<li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA">IntelliJ FAQ on migrating to IntelliJ IDEA</a></li>
</ol>
@@ -19,170 +26,178 @@ provides some tips to help you get started with some of the most common tasks an
enhancements. </p>
- <h2>Smart Rendering</h2>
- <p>With smart rendering, Android Studio displays links for quick fixes to rendering errors.
- For example, if you add a button to the layout without specifying the <em>width</em> and
- <em>height</em> attributes, Android Studio displays the rendering message <em>Automatically
- add all missing attributes</em>. Clicking the message adds the missing attributes to the layout.</p>
+<h2 id="productivity-features">Productivity Shortcuts</h2>
+
+<p>Android Studio includes a number of features to help you be more productive in your coding.
+This section notes a few of the key features to help you work quickly and efficiently.
+</p>
+
+
+<h3>Smart Rendering</h3>
+<p>With smart rendering, Android Studio displays links for quick fixes to rendering errors.
+For example, if you add a button to the layout without specifying the <em>width</em> and
+<em>height</em> attributes, Android Studio displays the rendering message <em>Automatically
+add all missing attributes</em>. Clicking the message adds the missing attributes to the layout.</p>
- <h2> Bitmap rendering in the debugger</h2>
- <p>While debugging, you can now right-click on bitmap variables in your app and invoke
- <em>View Bitmap</em>. This fetches the associated data from the debugged process and renders
- the bitmap in the debugger. </p>
- <p><img src="{@docRoot}images/tools/studio-bitmap-rendering.png" style="width:350px"/></p>
- <p class="img-caption"><strong>Figure 13.</strong> Bitmap Rendering/p>
+<h3> Bitmap rendering in the debugger</h3>
+<p>While debugging, you can now right-click on bitmap variables in your app and invoke
+<em>View Bitmap</em>. This fetches the associated data from the debugged process and renders
+the bitmap in the debugger. </p>
+<p><img src="{@docRoot}images/tools/studio-bitmap-rendering.png" style="width:350px"/></p>
+<p class="img-caption"><strong>Figure 1.</strong> Bitmap Rendering</p>
- <h2>Output window message filtering</h2>
- <p>When checking build results, you can filter messages by <em>message type</em> to quickly
- locate messages of interest.</p>
- <img src="{@docRoot}images/tools/studio-outputwindowmsgfiltering.png" style="width:200px"style="width:200px" />
- <p class="img-caption"><strong>Figure 14.</strong> Filter Build Messages</p>
+<h3>Creating new files</h3>
+<p>You can quickly add new code and resource files by clicking the appropriate directory in the
+<strong>Project</strong> pane and pressing <code>ALT + INSERT</code> on Windows and Linux or
+<code>COMMAND + N</code> on Mac. Based on the type of directory selected, Android Studio
+offers to create the appropriate file type.</p>
+<p>For example, if you select a layout directory, press <code>ALT + INSERT</code> on Windows,
+and select <strong>Layout resource file</strong>, a dialog opens so you can name the file
+(you can exclude the {@code .xml} suffix) and choose a root view element. The editor then
+switches to the layout design editor so you can begin designing your layout.</p>
- <h2>Hierarchical parent setting</h2>
- <p>The activity parent can now be set in the Activity Wizard when creating a new
- activity. Setting a <em>hierarchal parent</em> sets the {@code Up} button to automatically
- appear in the app's Action bar when viewing a child activity, so the {@code Up}
- button no longer needs to be manually specified in the <em>menu.xml</em> file.</p>
+<h3>Output window message filtering</h3>
+<p>When checking build results, you can filter messages by <em>message type</em> to quickly
+locate messages of interest.</p>
+<img src="{@docRoot}images/tools/studio-outputwindowmsgfiltering.png" style="width:200px"style="width:200px" />
+<p class="img-caption"><strong>Figure 2.</strong> Filter Build Messages</p>
- <h2>Creating layouts</h2>
- <p>Android Studio offers an advanced layout editor that allows you to drag-and-drop widgets
- into your layout and preview your layout while editing the XML.</p>
- <p>While editing in the <strong>Text</strong> view, you can preview the layout on devices by
- opening the <strong>Preview</strong> pane available on the right side of the window. Within the
- Preview pane, you can modify the preview by changing various options at the top of the pane,
- including the preview device, layout theme, platform version and more. To preview the layout on
- multiple devices simultaneously, select <strong>Preview All Screen Sizes</strong> from the
- device drop-down.</p>
- <p><img src="{@docRoot}images/tools/studio-previewall.png" style="width:350px"/></p>
- <p class="img-caption"><strong>Figure 15.</strong> Preview All Screens/p>
+<h3>Hierarchical parent setting</h3>
+<p>The activity parent can now be set in the Activity Wizard when creating a new
+activity. Setting a <em>hierarchal parent</em> sets the {@code Up} button to automatically
+appear in the app's Action bar when viewing a child activity, so the {@code Up}
+button no longer needs to be manually specified in the <em>menu.xml</em> file.</p>
- <p>You can switch to the graphical editor by clicking <strong>Design</strong> at the
- bottom of the window. While editing in the Design view, you can show and hide the
- widgets available to drag-and-drop by clicking <strong>Palette</strong> on the left side of the
- window. Clicking <strong>Designer</strong> on the right side of the window reveals a panel
- with a layout hierarchy and a list of properties for each view in the layout.</p>
+<h3>Creating layouts</h3>
+<p>Android Studio offers an advanced layout editor that allows you to drag-and-drop widgets
+into your layout and preview your layout while editing the XML.</p>
- <h3>Annotations</h3>
- <p>Android Studio provides coding assistance for using annotations from the
- {@link android.support.annotation Support-Annotations} library, part of the
- Support Repository. Adding a dependency for this library enables you to decorate your code with
- annotations to help catch bugs, such as null pointer exceptions and resource type conflicts.
- You can also create enumerated annotations to, for example, check that a passed parameter value
- matches a value from a defined set of constants. For more information, see
- <a href="{@docRoot}tools/debugging/annotations.html#annotations">Improving Code Inspection with
- Annotations</a>. </p>
+<p>While editing in the <strong>Text</strong> view, you can preview the layout on devices by
+opening the <strong>Preview</strong> pane available on the right side of the window. Within the
+Preview pane, you can modify the preview by changing various options at the top of the pane,
+including the preview device, layout theme, platform version and more. To preview the layout on
+multiple devices simultaneously, select <strong>Preview All Screen Sizes</strong> from the
+device drop-down.</p>
+<p><img src="{@docRoot}images/tools/studio-previewall.png" style="width:350px"/></p>
+<p class="img-caption"><strong>Figure 3.</strong> Preview All Screens</p>
+<p>You can switch to the graphical editor by clicking <strong>Design</strong> at the
+bottom of the window. While editing in the Design view, you can show and hide the
+widgets available to drag-and-drop by clicking <strong>Palette</strong> on the left side of the
+window. Clicking <strong>Designer</strong> on the right side of the window reveals a panel
+with a layout hierarchy and a list of properties for each view in the layout.</p>
- <h3>Java class decompiling</h3>
- <p>Android Studio allows you to look at what’s inside Java libraries when you don’t have access
- to the source code. </p>
- <p>The decompiler is built into Android Studio for easy access. To use this feature, right-click
- a class, method, or field from a library for which you do not have source file access and select
- <strong>decompile</strong>.</p> The decompiled source code appears. </p>
+<h3>Annotations</h3>
+<p>Android Studio provides coding assistance for using annotations from the
+{@link android.support.annotation Support-Annotations} library, part of the
+Support Repository.
- <p>To adjust the Java decompiler settings, select
- <strong>File > Settings > Other Settings > Java Decompiler</strong>. </p>
+Adding a dependency for this library enables you to decorate your code with annotations to help
+catch bugs, such as null pointer exceptions and resource type conflicts. You can also create
+enumerated annotations to, for example, check that a passed parameter value matches a value from
+a defined set of constants. For more information, see
+<a href="{@docRoot}tools/debugging/annotations.html#annotations">Improving Code Inspection with
+Annotations</a>.
+</p>
- <h3>Debugging and performance enhancements</h3>
- <p>Android Studio offers debugging and performance enhancements such as:</p>
- <ul>
- <li>Auto detect an expanded set of code styles. To modify the current code style, choose
- <strong>File &gt; Settings &gt; Code Styles</strong>. </li>
- <li>Support for high density (Retina) displays on Windows and Linux. </li>
- <li>Scratch files for quick prototyping without creating any project files.
- <p>Choose <strong>Tools &gt; New Scratch File</strong> to open a scratch file to quickly
- build and run code prototypes. Together with Android Studio coding assistance, scratch
- files allow you to quickly run and debug code updates with the support of all file operations.
- By embedding code created with scripting languages, you can run your code from within the
- scratch file.</p>
- </li>
- </ul>
+<h3>Java class decompiling</h3>
+<p>Android Studio allows you to look at what’s inside Java libraries when you don’t have access
+to the source code. </p>
+<p>The decompiler is built into Android Studio for easy access. To use this feature, right-click
+a class, method, or field from a library for which you do not have source file access and select
+<strong>decompile</strong>.</p> The decompiled source code appears. </p>
+<p>To adjust the Java decompiler settings, select
+<strong>File > Settings > Other Settings > Java Decompiler</strong>. </p>
-<h2 id="intellij">Working with IntelliJ-based Coding Practices</h2>
- <p>This section list just a few of the code editing
- practices you should consider using when creating Android Studio apps. </p>
+<h3>Debugging and performance enhancements</h3>
+<p>Android Studio offers debugging and performance enhancements such as:</p>
+<ul>
+ <li>Custom keymaps. To modify the current keymap, choose
+ <strong>File &gt; Settings &gt; Keymap</strong>. </li>
+ <li>Support for high density (Retina) displays on Windows and Linux. </li>
+ <li>Scratch files for quick prototyping without creating any project files.
+ <p>Choose <strong>Tools &gt; New Scratch File</strong> to open a scratch file to quickly
+ build and run code prototypes. Together with Android Studio coding assistance, scratch
+ files allow you to quickly run and debug code updates with the support of all file operations.
+ By embedding code created with scripting languages, you can run your code from within the
+ scratch file.</p>
+ </li>
+</ul>
- <p>For complete user documentation for the IntelliJ IDEA interface (upon which Android Studio
- is based), refer to the
- <a href="http://www.jetbrains.com/idea/documentation/index.jsp">IntelliJ IDEA documentation</a>.</p>
- <h3><em>Alt + Enter</em> key binding</h3>
- <p>For quick fixes to coding errors, the IntelliJ powered IDE implements the <em>Alt + Enter</em>
- key binding to fix errors (missing imports, variable assignments, missing references, etc) when
- possible, and if not, suggest the most probable solution. </p>
+<h2 id="intellij">Working with IntelliJ-based Coding Practices</h3>
- <h3><em>Ctrl + D</em> key binding</h3>
- <p>The <em>Ctrl + D</em> key binding is great for quickly duplicating code lines or fragments.
- Simply select the desired line or fragment and enter this key binding. </p>
+<p>This section list just a few of the code editing
+practices you should consider using when creating Android Studio apps. </p>
- <h3>Navigate menu</h3>
- <p>In case you're not familiar with an API class, file or symbol, the <em>Navigate</em> menu lets
- you jump directly to the class of a method or field name without having to search through
- individual classes. </p>
+<p>For complete user documentation for the IntelliJ IDEA interface (upon which Android Studio
+is based), refer to the
+<a href="http://www.jetbrains.com/idea/documentation/index.jsp">IntelliJ IDEA documentation</a>.</p>
- <h3>Inspection scopes</h3>
- <p>Scopes set the color of code segments for easy code identification and location. For example,
- you can set a scope to identify all code related to a specific action bar. </p>
+<h3><em>Alt + Enter</em> key binding</h3>
+<p>For quick fixes to coding errors, the IntelliJ powered IDE implements the <em>Alt + Enter</em>
+key binding to fix errors (missing imports, variable assignments, missing references, etc) when
+possible, and if not, suggest the most probable solution. </p>
+<h3><em>Ctrl + D</em> key binding</h3>
+<p>The <em>Ctrl + D</em> key binding is great for quickly duplicating code lines or fragments.
+Simply select the desired line or fragment and enter this key binding. </p>
- <h3>External annotations</h3>
- <p>Specify annotations within the code or from an external annotation file. The Android Studio
- IDE keeps track of the restrictions and validates compliance, for example setting the data type
- of a string as not null.</p>
+<h3>Navigate menu</h3>
+<p>In case you're not familiar with an API class, file or symbol, the <em>Navigate</em> menu lets
+you jump directly to the class of a method or field name without having to search through
+individual classes. </p>
- <h3>Injecting languages</h3>
- <p>With language injection, the Android Studio IDE allows you to work with islands of different
- languages embedded in the source code. This extends the syntax, error highlighting and coding
- assistance to the embedded language. This can be especially useful for checking regular expression
- values inline, and validating XML and SQL statements.</p>
- <h3>Code folding</h3>
- <p>This allows you to selectively hide and display sections of the code for readability. For
- example, resource expressions or code for a nested class can be folded or hidden in to one line
- to make the outer class structure easier to read. The inner class can be later expanded for
- updates. </p>
+<h3>Inspection scopes</h3>
+<p>Scopes set the color of code segments for easy code identification and location. For example,
+you can set a scope to identify all code related to a specific action bar. </p>
- <h3>Image and color preview</h3>
- <p>When referencing images and icons in your code, a preview of the image or icon appears
- (in actual size at different densities) in the code margin to help you verify the image or icon
- reference. Pressing {@code F1} with the preview image or icon selected displays resource asset
- details, such as the <em>dp</em> settings. </p>
+<h3>Injecting languages</h3>
+<p>With language injection, the Android Studio IDE allows you to work with islands of different
+languages embedded in the source code. This extends the syntax, error highlighting and coding
+assistance to the embedded language. This can be especially useful for checking regular expression
+values inline, and validating XML and SQL statements.</p>
- <h3>Quick F1 documentation</h3>
- <p>You can now inspect theme attributes using <strong>View > Quick Documentation</strong>
- (<strong>F1</strong>),
- see the theme inheritance hierarchy, and resolve values for the various attributes.</p>
+<h3>Code folding</h3>
+<p>This allows you to selectively hide and display sections of the code for readability. For
+example, resource expressions or code for a nested class can be folded or hidden in to one line
+to make the outer class structure easier to read. The inner class can be later expanded for
+updates. </p>
- <p>If you invoke <strong> View > Quick Documentation</strong> (usually bound to F1) on the theme
- attribute <em>?android:textAppearanceLarge</em>, you will see the theme inheritance hierarchy and
- resolved values for the various attributes that are pulled in.</p>
+<h3>Image and color preview</h3>
+<p>When referencing images and icons in your code, a preview of the image or icon appears
+(in actual size at different densities) in the code margin to help you verify the image or icon
+reference. Pressing {@code F1} with the preview image or icon selected displays resource asset
+details, such as the <em>dp</em> settings. </p>
- <h3>New Allocation Tracker integration in the Android/DDMS window</h3>
- <p>You can now inspect theme attributes using <strong> View > Quick Documentation
- </strong> <code>F1</code>, see the theme inheritance hierarchy, and resolved values for the
- various attributes.</p>
- <img src="{@docRoot}images/tools/studio-allocationtracker.png" style="width:300px" />
- <p class="img-caption"><strong>Figure 16</strong> Allocation Tracker</p>
+<h3>Quick F1 documentation</h3>
+<p>You can now inspect theme attributes using <strong>View > Quick Documentation</strong>
+(<strong>F1</strong>),
+see the theme inheritance hierarchy, and resolve values for the various attributes.</p>
+<p>If you invoke <strong> View > Quick Documentation</strong> (usually bound to F1) on the theme
+attribute <em>?android:textAppearanceLarge</em>, you will see the theme inheritance hierarchy and
+resolved values for the various attributes that are pulled in.</p>
@@ -288,13 +303,5 @@ using Mac OS X, update your keymap to use the Mac OS X 10.5+ version keymaps und
</table>
<p>For a complete keymap reference guide, see the
-<a href="http://www.jetbrains.com/idea/documentation/index.jsp">IntelliJ IDEA</a> documentation.</p>
-
-
-</div>
-
-
-</div>
-
-
-
+<a href="http://www.jetbrains.com/idea/documentation/index.jsp">IntelliJ IDEA</a>
+documentation.</p>
diff --git a/docs/html/tools/building/building-cmdline-ant.jd b/docs/html/tools/building/building-cmdline-ant.jd
index 51158de..add6ca2 100644
--- a/docs/html/tools/building/building-cmdline-ant.jd
+++ b/docs/html/tools/building/building-cmdline-ant.jd
@@ -31,6 +31,14 @@ Emulator</a></li>
</div>
</div>
+<p class="caution">
+ <strong>Important:</strong> Support for Ant as a build tool for Android is ending, per our
+ <a href="http://android-developers.blogspot.com/2015/06/an-update-on-eclipse-android-developer.html"
+ class="external-link">announcement</a>. You should migrate your app development projects to
+ Android Studio and Gradle as soon as possible. For more information on transitioning to these
+ tools, see <a href="{@docRoot}sdk/installing/migrate.html">Migrating to Android Studio</a>.
+</p>
+
<p>There are two ways to build your application using the Ant build script: one for
testing/debugging your application &mdash; <em>debug mode</em> &mdash; and one for building your
final package for release &mdash; <em>release mode</em>. Regardless of which way you build your application,
diff --git a/docs/html/tools/building/configuring-gradle.jd b/docs/html/tools/building/configuring-gradle.jd
index 7cca5b4..73a048b 100644
--- a/docs/html/tools/building/configuring-gradle.jd
+++ b/docs/html/tools/building/configuring-gradle.jd
@@ -198,6 +198,75 @@ settings from the Android SDK installation. Android Studio adds the module-speci
<code>proguard-rules.pro</code> at the root of the module, where you can add custom ProGuard
rules.</p>
+
+
+<h3>Application ID for package identification </h3>
+<p>With the Android build system, the <em>applicationId</em> attribute is used to
+uniquely identify application packages for publishing. The application ID is set in the
+<em>android</em> section of the <code>build.gradle</code> file.
+</p>
+
+ <pre>
+ apply plugin: 'com.android.application'
+
+ android {
+ compileSdkVersion 19
+ buildToolsVersion "19.1"
+
+ defaultConfig {
+ <strong>applicationId "com.example.my.app"</strong>
+ minSdkVersion 15
+ targetSdkVersion 19
+ versionCode 1
+ versionName "1.0"
+ }
+ ...
+ </pre>
+
+<p class="note"><strong>Note:</strong> The <em>applicationId</em> is specified only in your
+{@code build.gradle} file, and not in the AndroidManifest.xml file.</p>
+
+<p>When using build variants, the build system enables you to uniquely identify different
+packages for each product flavors and build types. The application ID in the build type is added as
+a suffix to those specified for the product flavors. </p>
+
+ <pre>
+ productFlavors {
+ pro {
+ applicationId = "com.example.my.pkg.pro"
+ }
+ free {
+ applicationId = "com.example.my.pkg.free"
+ }
+ }
+
+ buildTypes {
+ debug {
+ applicationIdSuffix ".debug"
+ }
+ }
+ ....
+ </pre>
+
+<p>The package name must still be specified in the manifest file. It is used in your source code
+to refer to your R class and to resolve any relative activity/service registrations. </p>
+
+ <pre>
+ <?xml version="1.0" encoding="utf-8"?>
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ <strong>package="com.example.app"</strong>>
+ </pre>
+
+<p class="note"><strong>Note:</strong> If you have multiple manifests (for example, a product
+flavor specific manifest and a build type manifest), the package name is optional in those manifests.
+If it is specified in those manifests, the package name must be identical to the package name
+specified in the manifest in the <code>src/main/</code> folder. </p>
+
+<p>For more information about the build files and process, see
+<a href="{@docRoot}sdk/installing/studio-build.html">Build System Overview</a>.</p>
+
+
+
<h3 id="configureSigning">Configure signing settings</h3>
<p>The debug and the release versions of the app differ on whether the application can be
diff --git a/docs/html/tools/building/manifest-merge.jd b/docs/html/tools/building/manifest-merge.jd
new file mode 100644
index 0000000..54166ec
--- /dev/null
+++ b/docs/html/tools/building/manifest-merge.jd
@@ -0,0 +1,510 @@
+page.title=Manifest Merging
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#merge-rules">Merge Conflict Rules</a></li>
+ <li><a href="#markers-selectors">Merge Conflict Markers and Selectors</a></li>
+ <li><a href="#inject-values">Injecting Build Values into a Manifest</a></li>
+ <li><a href="#merge-prodflavorsGroups">Manifest Merging Across Product Flavor Groups</a></li>
+ <li><a href="#implicit-permissions">Implicit Permissions</a></li>
+ <li><a href="#merge-errors">Handling Manifest Merge Build Errors</a></li>
+ </ol>
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}sdk/installing/studio-build.html">Build System Overview</a></li>
+ <li><a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a> </li>
+ </ol>
+
+</div>
+</div>
+
+
+<p>With Android Studio and <a href="http://www.gradle.org">Gradle</a>-based builds, each app can
+contain manifest files in multiple locations, such as the <code>src/main/</code> folder for
+the <code>productFlavor</code>, libraries, Android ARchive (AAR) bundles of Android Library
+projects, and dependencies. During the build process, manifest merging combines the settings from
+the various <code>AndroidManifest.xml</code> files included in your app into a single, generated APK
+manifest file for app packaging and distribution. Manifest settings are merged based on the manifest
+priority, determined by the manifest's file location. Building your app merges the
+manifest elements, attributes, and sub-elements from these manifests for the specified
+<a href="{@docRoot}tools/building/configuring-gradle.html#workBuildVariants">build variant</a>.</p>
+
+
+<h2 id="merge-rules">Merge Conflict Rules</h2>
+<p>Merge conflicts occur when merged manifests contain the same manifest element but with a
+different attribute value that does not resolve based on the default merge conflict rules.
+<a href="#markers-selectors">Conflict markers and selectors</a> can also define custom merge rules,
+such as allowing an imported library to have a <code>minSdkVersion</code> higher than the
+version defined in the other higher priority manifests. </p>
+
+<p>The manifest merge priority determines which manifest settings are retained in merge conflicts,
+with the settings in higher priority manifest overwriting those in lower priority manifests.
+The following list details which manifest settings are are the highest priority during the merge
+process:</p>
+
+<ul>
+ <li>Highest priority: <code>buildType</code> manifest settings </li>
+ <li>Higher priority: <code>productFlavor</code> manifest settings </li>
+ <li>Medium priority: Manifests in the <code>src/main/</code> directory of an app project</li>
+ <li>Low priority: Dependency and library manifest settings </li>
+</ul>
+
+<p>Manifest merge conflicts are resolved at the XML node and
+attribute levels based on the following merge rules. </p>
+
+<table>
+ <tr>
+ <th scope="col">High Priority Element</th>
+ <th scope="col">Low Priority Element</th>
+ <th scope="col">Manifest Merge Result</th>
+ </tr>
+ <tr>
+ <td rowspan="3">no attribute</td>
+ <td>no attribute</td>
+ <td>no attribute</td>
+ </tr>
+ <tr>
+
+ <td>attribute set to default</td>
+ <td>default attribute</td>
+ </tr>
+ <tr>
+
+ <td>attribute set to non-default </td>
+ <td>low priority attribute</td>
+ </tr>
+ <tr>
+ <td>attribute set to default</td>
+ <td rowspan="2">no attribute</td>
+ <td>default attribute</td>
+ </tr>
+ <tr>
+ <td>attribute set to non-default </td>
+
+ <td>high priority attribute</td>
+ </tr>
+ <tr>
+ <td>attribute set to default</td>
+ <td>attribute set to default</td>
+ <td>default attribute</td>
+ </tr>
+ <tr>
+ <td>attribute set to default</td>
+ <td>attribute set to non-default </td>
+ <td>low priority attribute</td>
+ </tr>
+ <tr>
+ <td>attribute set to non-default</td>
+ <td>attribute set to default</td>
+ <td>high priority attribute</td>
+ </tr>
+ <tr>
+ <td>attribute set to non-default</td>
+ <td>attribute set to non-default </td>
+ <td>Merge if settings match, otherwise causes conflict error.</td>
+ </tr>
+ </table>
+
+
+
+<p>Exceptions to the manifest merge rules: </p>
+
+<ul>
+ <li>The <code>uses-feature android:required;</code> and
+ <code>uses-library android:required</code> elements default to <code>true</code> and use
+ an <em>OR</em> merge so that any required feature or library is included in the generated APK. </li>
+
+ <li>If not declared, the
+ <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><code>&lt;uses-sdk&gt;</code></a>
+ elements, <code>minSdkVersion</code> and
+ <code>targetSdkVersion</code>, default to a value of 1. When
+ merge conflicts occur, the value in the higher priority manifest version is used.</li>
+
+ <li>Importing a library with a <code>minSdkVersion</code> value higher than the app's
+ <code>src/main/</code> manifest manifest generates an error unless
+ the <code>overrideLibrary</code> conflict marker is used.
+
+ <p class="note"><strong>Note:</strong> If not explicitly declared, the <code>targetSdkVersion</code>
+ defaults to the <code>minSdkVersion</code> value. When no <code><uses-sdk></code> element is
+ present in any manifest or the <code>build.gradle</code> file, the
+ <code>minSdkVersion</code> defaults to 1.</p> </li>
+
+ <li>When importing a library with a <code>targetSdkVersion</code> value lower than the app's
+ <code>src/main/</code> manifest, the manifest merge
+ process explicitly grants permissions and ensures that the imported library functions properly. </li>
+
+ <li>The <code>manifest</code> element only merges with child manifest elements. </li>
+
+ <li>The <code>intent-filter</code> element is never changed and is always added to the common
+ parent node in the merged manifest. </li>
+</ul>
+
+<p class="caution"><strong>Important:</strong> After the manifests are merged, the build process
+overrides the final manifest settings with any settings that are also in the
+<code>build.gradle</code> file. For more details, see
+<a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a>. </p>
+
+
+
+<h2 id="markers-selectors">Merge Conflict Markers and Selectors</h2>
+<p>Manifest markers and selectors override the default merge rules through
+specific conflict resolutions. For example, use a conflict marker to
+merge a library manifest with a higher <code>minSdkVersion</code> value than the higher priority
+manifest, or to merge manifests with the same activity but different <code>android:theme</code>
+values. </p>
+
+<h3 id="conflict-markers">Merge Conflict Markers</h3>
+<p>A merge conflict marker is a special attribute in the Android tools namespace that defines a
+specific merge conflict resolution. Create a conflict marker to avoid a merge conflict error for
+conflicts not resolved by the default merge rules. Supported merge conflict markers include:</p>
+
+<dl>
+ <dt><code>merge</code></dt>
+ <dd>Merges attributes when there are no conflicts with the merge rules. The default merge
+ action.</dd>
+ <dt><code>replace</code></dt>
+ <dd>Replaces attributes in the lower priority manifest with those from the higher priority
+ manifest.</dd>
+ <dt><code>strict</code></dt>
+ <dd>Sets the merge policy level so that merged elements with same attributes, but different
+ values generate a build failure, unless resolved through the conflict rules.</dd>
+ <dt><code>merge-only</code></dt>
+ <dd>Allows merge actions for only lower priority attributes.</dd>
+ <dt><code>remove</code></dt>
+ <dd>Removes the specified lower priority element from the merged manifest.</dd>
+ <dt><code>remove-All</code></dt>
+ <dd>Removes all lower priority elements of the same node type from the merged manifest.</dd>
+</dl>
+
+
+<p>By default, the manifest merge process applies the <code>merge</code> conflict marker to
+the node level. All declared manifest attributes default to a <code>strict</code>
+merging policy. </p>
+
+<p>To set a merge conflict marker, first declare the namespace in the
+<code>AndroidManifest.xml</code> file. Then, enter the merge conflict marker in the manifest to
+specify a custom merge conflict action. This example inserts the <code>replace</code> marker to
+set a replace action to resolve conflicts between the <code>android:icon</code> and
+<code>android:label</code> manifest elements. </p>
+
+<pre>
+
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.tests.flavorlib.app"
+ xmlns:tools="http://schemas.android.com/tools"&gt;
+
+ &lt;application
+ android:icon="&#64;drawable/icon"
+ android:label="&#64;string/app_name"
+ tools:replace="icon, label"&gt;
+ ...
+
+</manifest>
+
+</pre>
+
+
+<h4>Marker attributes</h4>
+<p>Conflict markers use <code>tools:node</code> and <code>tools:attr</code> attributes to
+restrict merge actions at the XML node or attribute level. </p>
+
+<p>The <code>tools:attr</code> markers use only the <code>restrict</code>, <code>remove</code>, and
+<code>replace</code> merge actions. Multiple <code>tools:attr</code> marker values can be applied
+to a specific element. For example, use <code>tools:replace="icon, label, theme"</code> to replace
+lower priority <code>icon</code>, <code>label</code>, and <code>theme</code> attributes. </p>
+
+
+<h4>Merge conflict marker for imported libraries</h4>
+<p>The <code>overrideLibrary</code> conflict marker applies to the <code>&lt;uses-sdk&gt;</code>
+manifest declaration and is used to import a library even though the library's
+<code>&lt;uses-sdk&gt;</code> values, such as <code>minSdkVersion</code>
+are set to different values than those in the other higher priority manifests. </p>
+
+<p>Without this marker, library manifest merge conflicts from the
+<code>&lt;uses-sdk&gt;</code> values cause the merge process to fail.</p>
+
+<p>This example applies the <code>overrideLibrary</code> conflict marker to resolve the merge
+conflict between <code>minSdkVersion</code> values in the <code>src/main/</code> manifest and an
+imported library manifest.
+
+
+<p><code>src/main/</code> manifest: </p>
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.example.app"
+ xmlns:tools="http://schemas.android.com/tools"&gt;
+ ...
+ &lt;uses-sdk android:targetSdkVersion="22" android:minSdkVersion="2"
+ tools:overrideLibrary="com.example.lib1, com.example.lib2"/&gt;
+ ...
+</pre>
+
+<p>Library manifest: </p>
+
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1"&gt;
+ ...
+ &lt;uses-sdk android:minSdkVersion="4" /&gt;
+ ...
+ &lt;/manifest&gt;
+</pre>
+
+<p class="note"><strong>Note:</strong> The default merge process does not allow importing a library
+with a higher <code>minSdkVersion</code> than the app's <code>src/main/</code> manifest unless
+the <code>overrideLibrary</code> conflict marker is used. </p>
+
+
+
+<h3 id="marker-selectors">Marker Selectors</h3>
+<p>Marker selectors limit a merge action to a specific lower priority manifest. For example, a
+marker selector can be used to remove a permission from only one library, while allowing the
+same permission from other libraries.</p>
+
+<p>This example uses the <code>tools:node</code> marker to remove the <code>permisionOne</code>
+attribute, while the <code>tools:selector</code> selector specifies the specific library as
+<em>com.example.lib1</em>. The <code>permisionOne</code> permission is filtered from only the
+<code>lib1</code> library manifests. </p>
+
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.example.app"
+ xmlns:tools="http://schemas.android.com/tools"&gt;
+ ...
+ &lt;permission
+ android:name="permissionOne"
+ tools:node="remove"
+ tools:selector="com.example.lib1"&gt;
+ ...
+</pre>
+
+
+
+<h2 id="inject-values">Injecting Build Values into a Manifest</h2>
+<p>Manifest merging can also be configured to use manifest placeholders to inject
+property values from the <code>build.gradle</code> file into the manifest attributes. </p>
+
+<p>Manifest placeholders use the syntax <code>&#36;{name}</code> for attribute values, where
+<code>name</code> is the injected <code>build.gradle</code> property. The <code>build.gradle</code>
+file uses the <code>manifestPlaceholders</code> property to define the placeholder values. </p>
+
+<p class="note"><strong>Note:</strong> Unresolved placeholder names in apps cause build failures.
+Unresolved placeholder names in libraries generate warnings and need to be resolved when importing
+the library into an app.</p>
+
+<p>This example shows the manifest placeholder <code>&#36;{applicationId}</code> used to inject the
+<code>build.gradle</code> <code>applicationId</code> property value in to <code>android:name</code>
+attribute value. </p>
+
+<p class="note"><strong>Note:</strong> Android Studio provides a default
+<code>&#36;{applicationId}</code> placeholder for the <code>build.gradle</code>
+<code>applicationId</code> value that is not shown in the build file.</p>
+
+
+<p>Manifest entry:</p>
+
+<pre>
+
+&lt;activity
+android:name=".Main"&gt;
+ &lt;intent-filter&gt;
+ &lt;action android:name="&#36;{applicationId}.foo"&gt;
+ &lt;/action&gt;
+&lt;/intent-filter&gt;
+&lt;/activity&gt;
+
+</pre>
+
+
+<p>Gradle build file:</p>
+
+<pre>
+android {
+ compileSdkVersion 22
+ buildToolsVersion "22.0.1"
+
+ productFlavors {
+ flavor1 {
+ applicationId = "com.mycompany.myapplication.productFlavor1"
+ }
+}
+
+</pre>
+
+<p>Merged manifest value: </p>
+
+<pre>
+&lt;action android:name="com.mycompany.myapplication.productFlavor1.foo"&gt;
+</pre>
+
+
+<p>The manifest placeholder syntax and build file <code>manifestPlaceholders</code>
+property can be used to inject other manifest values. For properties other than the
+<code>applicationId</code>, the <code>manifestPlaceholders</code> property is explicitly declared
+in the <code>build.gradle</code> file. This example shows the manifest placeholder for injecting
+<code>activityLabel</code> values.</p>
+
+<p>Gradle build file: </p>
+
+<pre>
+android {
+ defaultConfig {
+ manifestPlaceholders = [ activityLabel:"defaultName"]
+ }
+ productFlavors {
+ free {
+ }
+ pro {
+ manifestPlaceholders = [ activityLabel:"proName" ]
+ }
+ }
+
+</pre>
+
+<p>Placeholder in the manifest file: </p>
+
+<pre>
+&lt;activity android:name=".MainActivity" android:label="&#36;{activityLabel}" &gt;
+</pre>
+
+<p class="note"><strong>Note:</strong> The placeholder value supports partial value injection,
+for example <code>android:authority="com.acme.&#36;{localApplicationId}.foo"</code>. </p>
+
+
+
+<h2 id="merge-prodflavorsGroups">Manifest Merging Across Product Flavor Groups</h2>
+
+<p>When using the <code>GroupableProductFlavor</code> property, the manifest merge
+priority of any manifests in the product flavor groups follows the order in which the
+product flavor groups are listed in the build file. The manifest merge process creates a single
+merged manifest for the product flavor groups based on the configured build variant. </p>
+
+<p>For example, if a build variant references the product flavors <code>x86</code>,
+<code>mdpi</code>, <code>21</code>, and <code>paid</code> from the respective product flavor
+groups <code>ABI</code>, <code>Density</code>, <code>API</code>, and <code>Prod</code>, listed
+in this order in the <code>build.gradle</code> file, then the manifest merge process merges the
+manifests in this priority order, which follows how the product flavors are listed in the build
+file.</p>
+
+<p>To illustrate this example, the following table shows how the product flavors are listed for
+each product flavor group. This combination of product flavors and groups defines the
+build variant. </p>
+<table>
+ <tr>
+ <th scope="col">Product Flavor Group</th>
+ <th scope="col">Product Flavor</th>
+ <tr>
+ <td>ABI</td>
+ <td>x86</td>
+ </tr>
+ <tr>
+ <td>density</td>
+ <td>mdpi</td>
+ </tr>
+ <tr>
+ <td>API</td>
+ <td>22</td>
+ </tr>
+ <tr>
+ <td>prod</td>
+ <td>paid</td>
+ </tr>
+</table>
+
+<p>Manifest merge order:</p>
+
+ <ul>
+ <li>prod-paid AndroidManifest.xml (lowest priority) merges into API-22 AndroidManifest.xml</li>
+ <li>API-22 AndroidManifest.xml merges into density-mpi AndroidManifest.xml</li>
+ <li>density-mpi AndroidManifest.xml merges into ABI-x86 AndroidManifest.xml (highest priority)</li>
+ </ul>
+
+
+<h2 id="implicit-permissions">Implicit Permissions</h2>
+<p>Importing a library that targets an Android runtime with implicitly
+granted permissions may automatically add the permissions to the resulting merged manifest.
+For example, if an application with a <code>targetSdkVersion</code> of 16 imports a library with a
+<code>targetSdkVersion</code> of 2, Android Studio adds the <code>WRITE_EXTERNAL_STORAGE</code>
+permission to ensure permission compatibility across the SDK versions.
+
+<p class="note"><strong>Note:</strong> More recent Android releases replace implicit
+permissions with permission declarations.</p>
+
+
+This table lists the importing library versions and the declared permissions.
+</p>
+
+ <table>
+ <tr>
+ <th>Importing this library version</th>
+ <th>Declares this permission in the manifest </th>
+ </tr>
+ <tr>
+ <td><code>targetSdkVersion</code> &lt; 2 </td>
+ <td><code>WRITE_EXTERNAL_STORAGE</code> </td>
+ </tr>
+ <tr>
+ <td><code>targetSdkVersion</code> &lt; 4 </td>
+ <td><code>WRITE_EXTERNAL_STORAGE</code>, <code>READ_PHONE_STATE</code> </td>
+ </tr>
+ <tr>
+ <td>Declared <code>WRITE_EXTERNAL_STORAGE</code></td>
+ <td><code>READ_EXTERNAL_STORAGE</code></td>
+ </tr>
+ <tr>
+ <td><code>targetSdkVersion</code> &lt; 16 and using the <code>READ_CONTACTS</code>
+ permission</td>
+ <td><code>READ_CALL_LOG</code></td>
+ </tr>
+ <tr>
+ <td><code>targetSdkVersion</code> &lt; 16 and using the <code>WRITE_CONTACTS</code>
+ permission</td>
+ <td><code>WRITE_CALL_LOG</code></td>
+ </tr>
+ </table>
+
+
+
+<h2 id="merge-errors">Handling Manifest Merge Build Errors</h2>
+<p>During the build process, the manifest merge process stores a record of each merge transaction
+in the <code>manifest-merger-&lt;productFlavor&gt;-report.txt</code> file in the module
+<code>build/outputs/logs</code> folder. A different log file is generated for each of the
+module's build variants. </p>
+
+<p>When a manifest merge build error occurs, the merge process records the error message
+describing the merge conflict in the log file. For example, the
+<code>android:screenOrientation</code> merge conflict between the following manifests causes
+a build error. </p>
+
+<p>Higher priority manifest declaration: </p>
+
+<pre>
+&lt;activity
+ android:name="com.foo.bar.ActivityOne"
+ android:screenOrientation="portrait"
+ android:theme="&#64;theme1"/&gt;
+</pre>
+
+<p>Lower priority manifest declaration: </p>
+
+<pre>
+&lt;activity
+ android:name="com.foo.bar.ActivityOne"
+ android:screenOrientation="landscape"/&gt;
+</pre>
+
+<p>Error log:</p>
+
+<pre>
+/project/app/src/main/AndroidManifest.xml:3:9 Error:
+ Attribute activity&#64;screenOrientation value=(portrait) from AndroidManifest.xml:3:9
+ is also present at flavorlib:lib1:unspecified:3:18 value=(landscape)
+ Suggestion: add 'tools:replace="icon"' to <activity> element at AndroidManifest.xml:1:5 to override
+</pre>
+
+
diff --git a/docs/html/tools/help/adt.jd b/docs/html/tools/help/adt.jd
index 8abe1b4..0fac62d 100644
--- a/docs/html/tools/help/adt.jd
+++ b/docs/html/tools/help/adt.jd
@@ -30,20 +30,21 @@ page.tags=adt
</div>
</div>
- <p>ADT (Android Developer Tools) is a plugin for Eclipse that provides a suite of
+<p class="caution">
+ <strong>Important:</strong> Support for the Android Developer Tools (ADT) in Eclipse is ending,
+ per our <a href=
+ "http://android-developers.blogspot.com/2015/06/an-update-on-eclipse-android-developer.html"
+ class="external-link">announcement</a>. You should migrate your app development projects to
+ Android Studio as soon as possible. For more information on transitioning to Android Studio, see
+ <a href="{@docRoot}sdk/installing/migrate.html">Migrating to Android Studio</a>.
+</p>
+
+ <p>Android Developer Tools (ADT) is a plugin for Eclipse that provides a suite of
tools that are integrated with the Eclipse IDE. It offers you access to many features that help
you develop Android applications. ADT
provides GUI access to many of the command line SDK tools as well as a UI design tool for rapid
prototyping, designing, and building of your application's user interface.</p>
-<p class="note"><strong>Note:</strong>
-If you have been using Eclipse with ADT, be aware that <a
-href="{@docRoot}tools/studio/index.html">Android Studio</a> is now the official IDE
-for Android, so you should migrate to Android Studio to receive all the
-latest IDE updates. For help moving projects,
-see <a href="/sdk/installing/migrate.html">Migrating to Android
-Studio</a>.</p>
-
<p>If you still wish to use the ADT plugin for Eclipse, see
<a href="{@docRoot}sdk/installing/installing-adt.html">Installing Eclipse Plugin.</a>
</p>
diff --git a/docs/html/tools/studio/eclipse-transition-guide.jd b/docs/html/tools/studio/eclipse-transition-guide.jd
new file mode 100644
index 0000000..aaacbe3
--- /dev/null
+++ b/docs/html/tools/studio/eclipse-transition-guide.jd
@@ -0,0 +1,773 @@
+page.title=Transition Guide for Eclipse ADT
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+ <ol>
+ <li><a href="#project-structure">Project Structure</a></li>
+ <li><a href="#manifest-settings">Manifest Settings</a></li>
+ <li><a href="#dependencies">Dependencies</a></li>
+ <li><a href="#build-process">Gradle-based Build Process</a></li>
+ <li><a href="#debug-inspect">Debugging and Code Inspections</a></li>
+ <li><a href="#resource-optimization">Resource Optimization</a></li>
+ <li><a href="#signing">App Signing</a></li>
+ <li><a href="#support-lib">Android Support Repository and Google Play services Repository</a></li>
+ <li><a href="#app-package">App Packaging</a></li>
+ <li><a href="#software-updates">Software Updates </a></li>
+ <li><a href="#version-control">Version Control</a></li>
+ </ol>
+
+ <h2>See also</h2>
+ <ol>
+ <li><a class="external-link"
+ href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA">
+ IntelliJ FAQ on migrating to IntelliJ IDEA</a></li>
+ <li><a class="external-link"
+ href="https://confluence.jetbrains.com/display/IntelliJIDEA/IntelliJ+IDEA+for+Eclipse+Users">
+ IntelliJ IntelliJ for Eclipse Users</a></li>
+ <li><a href="{@docRoot}tools/studio/index.html">Android Studio Overview</a> </li>
+ </ol>
+
+</div>
+</div>
+
+
+<p>This document describes the differences between Eclipse ADT and Android Studio, including project
+ structure, build system, debugging, and application packaging. This guide is intended to help you
+ transition to using Android Studio as your development environment.</p>
+
+<h2 id="project-structure">Project Structure </h2>
+<p>Eclipse provides workspaces as a common area for grouping related projects, configurations, and
+settings. In Android Studio, each instance of Android Studio contains a top-level project with one
+or more app modules. Each app module folder contains the equivalent to an Eclipse
+project, the complete source sets for that module, including {@code src/main} and
+{@code src/androidTest} directories, resources, build file, and the Android manifest. In general,
+to update and build your app you modify the files under each module's
+{@code src/main} directory for source code updates, the <code>gradle.build</code> file for
+build specification, and the files under {@code src/androidTest} directory for test case creation. </p>
+
+<p>You can also customize the view of the project files in Android Studio to focus on specific
+aspects of your app development: </p>
+
+<ul>
+ <li><em>Packages</em> </li>
+ <li><em>Project Files</em> </li>
+ <li><em>Scratches</em> </li>
+ <li><em>Problems</em> </li>
+ <li><em>Production</em> </li>
+ <li><em>Tests</em> </li>
+</ul>
+
+
+<p>The following table shows the general mapping of the Eclipse ADT project structure and file
+locations to Android Studio.</p>
+
+<p class="table-caption" id="table-project-structure-mapping">
+ <strong>Table 1.</strong> Project structure mapping.</p>
+
+<table>
+ <tr>
+ <th scope="col">Eclipse ADT</th>
+ <th scope="col">Android Studio</th>
+ </tr>
+
+ <tr>
+ <td>Workspace </td>
+ <td>Project </td>
+ </tr>
+
+ <tr>
+ <td>Project </td>
+ <td>Module </td>
+ </tr>
+
+ <tr>
+ <td>Project-specific JRE </td>
+ <td>Module JDK </td>
+ </tr>
+
+ <tr>
+ <td>Classpath variable </td>
+ <td>Path variable</td>
+ </tr>
+
+ <tr>
+ <td>Project dependency</td>
+ <td>Module dependency</td>
+ </tr>
+
+ <tr>
+ <td>Library Module</td>
+ <td>Library </td>
+ </tr>
+
+ <tr>
+ <td><code>AndroidManifest.xml</code></td>
+ <td><code>app/src/main/AndroidManifest.xml</code> </td>
+ </tr>
+ <tr>
+ <td><code>assets/</code></td>
+ <td><code>app/src/main/assets</code> </td>
+ </tr>
+ <tr>
+ <td><code>res/</code></td>
+ <td><code>app/src/main/res/</code> </td>
+ </tr>
+ <tr>
+ <td><code>src/</code></td>
+ <td><code>app/src/main/java/ </code> </td>
+ </tr>
+ <tr>
+ <td><code>tests/src/</code></td>
+ <td><code>app/src/androidTest/java/</code> </td>
+ </tr>
+
+ </table>
+
+
+
+<p>Table 2 shows Eclipse ADT and Android Studio project views. </p>
+
+<p class="table-caption" id="table2">
+ <strong>Table 2.</strong> Comparing project views.</p>
+<table>
+ <tbody><tr>
+ <th>Eclipse ADT</th>
+ <th>Android Studio Project View</th>
+ <th>Android Studio Android View</th>
+ </tr>
+ <tr>
+ <td><img src="{@docRoot}images/tools/eclipse-notepad-pre-import--structure.png"/> </td>
+ <td><img src="{@docRoot}images/tools/studio-import-project-structure-project.png"/> </td>
+ <td><img src="{@docRoot}images/tools/studio-import-project-structure-android.png"/> </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<p class="note"><strong>Note:</strong> Multiple instances of Android Studio can be used to develop
+independent projects. </p>
+
+
+
+
+<h2 id="manifest-settings">Manifest Settings</h2>
+<p>Android Studio and <a href="http://www.gradle.org">Gradle</a>-based builds support
+<a href="{@docRoot}tools/building/configuring-gradle.html#workBuildVariants"> build variants</a>,
+which are combinations of <code>productFlavor</code> and <code>buildTypes</code>, to customize
+your build outputs. To support these custom builds, several elements in the
+<code>AndroidManifest.xml</code> file are now properties in the <code>defaultConfig</code> and
+<code>productFlavors</code> blocks in the <code>build.gradle</code> file. The import process
+copies these manifest settings to the properties in the <code>build.gradle</code> file.
+These properties overwrite the settings in any other manifest files as shown in table 3. </p>
+
+<p class="table-caption" id="table-manifest-gradle-settings">
+ <strong>Table 3.</strong> Manifest and Gradle property settings.</p>
+<table>
+ <tr>
+ <th scope="col">Manifest Setting</th>
+ <th scope="col">build.gradle Setting</th>
+ </tr>
+ <tr>
+ <td><code>&lt;uses-sdk</code> <br>
+ <p><code>android:minSdkVersion</code></p>
+ <p><code>android:targetSdkVersion /&gt;</code></p>
+ </td>
+ <td> <br>
+ <p><code>minSdkVersion</code></p>
+ <p><code>targetSdkVersion</code></p> </td>
+ </tr>
+ <tr>
+ <td><code>&lt;manifest</code>
+ <p>package (Required in the default manifest file.) </p>
+ <p><code>android:versionCode</code></p>
+ <p><code>android:versionName /&gt;</code></p>
+ </td>
+ <td> <br>
+ <p><code>applicationId</code> (See
+ <a href="{@docRoot}tools/studio/index.html#app-id"> Application ID
+ for Package Identification</a>)</p>
+ <p><code>versionCode</code></p>
+ <p><code>versionName</code></p> </td>
+ </tr>
+
+ </table>
+
+
+<p>Although these settings may no longer appear in the default app manifest file, they are still
+valid manifest entries and may still appear in manifests from older projects, imported projects,
+dependencies, and libraries.</p>
+
+<p>The <code>package</code> element must still be specified in the manifest file. It is used in
+your source code to refer to your <code>R</code> class and to resolve any relative activity/service
+registrations. </p>
+
+<p class="note"><strong>Note:</strong> When multiple manifests are present in your app, for
+example a library manifest and a <code>src/main/</code> manifest, the build process combines
+the manifest settings into a single merged manifest based on the manifest priority and
+manifest merge settings. For more information about the manifest merge process and merge settings,
+see
+<a href="{@docRoot}tools/building/manifest-merger.html"> Manifest Merger</a>. </p>
+
+
+<h2>Application ID for package identification </h2>
+<p>With the Android build system, the <code>applicationId</code> attribute is used to
+uniquely identify application packages for publishing. The application ID is set in the
+<code>android</code> section of the <code>build.gradle</code> file. This field is populated in the
+build file as part of the migration process. </p>
+
+<pre>
+apply plugin: &#39;com.android.application&#39;
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.1"
+
+ defaultConfig {
+ <strong>applicationId "com.example.my.app"</strong>
+ minSdkVersion 15
+ targetSdkVersion 19
+ versionCode 1
+ versionName "1.0"
+ }
+ ...
+</pre>
+
+<p class="note"><strong>Note:</strong> The <code>applicationId</code> is specified only in your
+<code>build.gradle</code> file, and not in the <code>AndroidManifest.xml</code> file.</p>
+
+<p><a href="{@docRoot}tools/building/configuring-gradle.html#workBuildVariants">Build variants</a>
+enable you to uniquely identify different
+packages for each product flavor and build type. The application ID in the build type setting can
+be added as a suffix to the ID specified for the product flavors. The following example adds the
+<code>.debug</code> suffix to the application ID of the <code>pro</code> and <code>free</code>
+product flavors: </p>
+
+<pre>
+productFlavors {
+ pro {
+ applicationId = &quot;com.example.my.pkg.pro&quot;
+ }
+ free {
+ applicationId = &quot;com.example.my.pkg.free&quot;
+ }
+}
+
+buildTypes {
+ debug {
+ applicationIdSuffix &quot;.debug&quot;
+ }
+}
+....
+</pre>
+
+
+
+<h2 id="dependencies">Dependencies</h2>
+<p>During the import process, Android Studio imports the current Eclipse ADT dependencies and
+downloads any project libraries as Android Studio modules. The dependency declarations are added to
+the <code>build.gradle</code> file. The declarations include a
+<a href="#scopes">dependency scope</a>, such as
+<code>compile</code>, to specify in which builds the dependency is included. </p>
+
+<p>The following example shows how to add an external library JAR dependency so it's included in
+each compile:</p>
+
+<pre>
+dependencies {
+ compile files(&#39;libs/*.jar&#39;)
+}
+
+android {
+ ...
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> Android Studio supports the Android ARchive (AAR) format
+for the distribution of Android library projects as dependencies. For more information, see
+<a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a>. </p>
+
+
+<p>The import process replaces any well-known source libraries, binary libraries, and JAR files
+that have known Maven coordinates with Maven dependencies, so you no longer need to
+maintain these dependencies manually. </p>
+
+<p>Android Studio enables access to Maven, JCenter, and Ivy repositories with the
+<code>repositories</code> block in the <code>build.gradle</code> as a shortcut to specifying
+the URL of the repository.
+
+<p>If there are required repositories not declared in the <code>build.gradle</code> file, first add
+the repository to the <code>repositories</code> block, and then declare the dependencies in a way
+that Maven, JCenter, or Ivy declare their artifacts. The following example shows how to add the
+Maven repository with the guava 11.0.2 dependency using the <code>mavenCentral()</code> property: </p>
+
+<pre>
+repositories {
+ mavenCentral()
+}
+
+android {
+ ...
+}
+
+dependencies {
+ compile &#39;com.google.guava:guava:11.0.2&#39;
+ instrumentationtestCompile &#39;com.squareup.fast-android:1:0.4&#39;
+}
+
+</pre>
+
+<p>The Android Studio project created during the import process can also re-use any
+dependencies on other components. These components can be external binary packages or other
+<a href="http://www.gradle.org">Gradle</a> projects. If a dependency has dependencies of its own,
+those dependencies are also included in the new Android Studio project. </p>
+
+
+<p class="note"><strong>Note:</strong> If there were references to Eclipse ADT workspace library
+files in the <code>project.properties</code> or <code>.classpath</code> files
+that were not imported from the Eclipse project, you can now add dependencies to these library files
+in the <code>build.gradle</code> file. For more information, see
+<a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a>. </p>
+
+
+<h3 id="scopes">Dependency and compilation scopes </h3>
+<p>Android Studio supports compilation scopes to customize which dependencies get
+included in each build, for example assigning different dependencies to different
+<a href="{@docRoot}tools/building/configuring-gradle.html#workBuildVariants"> build variants</a>.</p>
+
+<p>This list shows the Android Studio scope names and definitions: </p>
+
+<ul>
+ <li>compile - <code>compile</code> </li>
+ <li>run time - <code>package</code></li>
+ <li>testCompile - <code>AndroidTestCompile</code></li>
+ <li>testRuntime - <code>AndroidTestRunPackage</code></li>
+ <li>buildTypeCompile - <code>buildTypeCompile</code> </li>
+ <li>productFlavorCompile - <code>productFlavorCompile</code> </li>
+</ul>
+
+<p class="note"><strong>Note:</strong> Dependencies for library projects must be added with the
+<code>compile</code> scope. </p>
+
+
+<p>With the <a href="http://www.gradle.org">Gradle</a>-based DSL, you can also add custom
+dependency scopes, such as <code>betaCompile file('libs/protobug.jar')</code> to define a beta
+build dependency. </p>
+
+<p>The scope and compilation configuration in the build file determine the
+components compiled into the app, added to the compilation classpath, and packaged in the final
+APK file. Based on the dependency and compilation scope, different compilation configurations
+can be specified to include the dependencies and classpaths, for example: </p>
+
+<ul>
+<li><code>compile</code> - for the main application. </li>
+<li><code>androidTestCompile</code> - for the test application. </li>
+<li><code>debugCompile</code> - for the debug buildType application.</li>
+<li><code>releaseCompile</code> - for the release buildType application. </li>
+</ul>
+
+<p class="note"><strong>Note:</strong> Because it’s not possible to build an APK that does not
+have an associated <code>buildType</code>, the APK built from your app is always configured with
+at least two dependency and compile configurations: <code>compile</code> and
+<code>debugCompile</code>. </p>
+
+<p>Unlike Eclipse ADT, by default Android Studio does not compile your code when there are changes.
+Use the <strong>File &gt; Settings &gt; Build, Execution, Deployment Compiler</strong> option
+to enable automatic compilation. </p>
+
+
+
+<h2 id="build-process">Gradle-based Build Process </h2>
+<p>Android Studio imports the Eclipse ADT Ant-based
+build tasks and converts the tasks to <a href="http://www.gradle.org">Gradle</a>-based build tasks.
+These new build tasks include the
+main <code>assemble</code> task and at least two outputs based on the default build types:
+a <code>debug</code> APK and a
+<code>release</code> APK. Each of these build tasks has its own Android build system anchor task
+to facilitate building them independently: </p>
+<ul>
+ <li><code>assemble</code></li>
+ <li><code>assembleDebug</code></li>
+ <li><code>assembleRelease</code></li>
+</ul>
+
+<p>In Android Studio, you can view all the supported build tasks in the
+<em>Gradle</em> project tab. </p>
+
+<p>With the <a href="http://www.gradle.org">Gradle</a>-based build system, Android Studio uses a
+<a href="http://www.gradle.org">Gradle</a> wrapper to fully integrate the
+Android Plugin for Gradle. The Android Plugin for Gradle also
+runs independent of Android Studio. This means that with Android Studio build system your build
+output is always the same, whether you build your Android apps from Android Studio, from the
+command line on your machine, or on machines where Android Studio is not installed (such as
+continuous integration servers). </p>
+
+<p>Unlike Eclipse ADT with dependent plugin and build updates, the <code>build.gradle</code>
+files allow you to customize the build settings for each Android Studio module and build variant,
+so the build versions can be set independently, and are not dependent on the Android Studio
+or build tools versions. This makes it easy to maintain and build legacy apps along with your
+current app, using build variants to generate different APKs from the same app modules, but
+built with different build versions and build chains. </p>
+
+<p>For more details about the Android Studio build system, see
+<a href="{@docRoot}sdk/installing/studio-build.html">Build System Overview</a>.</p>
+
+<h3>Using the Android Studio build system's declarative logic </h3>
+<p>In contrast with the XML statements in Ant build files, the Android build system and
+<a href="http://www.gradle.org">Gradle</a> DSL provide a declarative build language so you can
+easily extend the Gradle-based build process beyond the typical XML build tasks. For example,
+this build file shows how to define a custom function to inject a dynamic <code>versionCode</code>
+in build outputs: </p>
+
+<pre>
+def getVersionCode) {
+ def code = …
+ return code
+}
+
+android {
+ defaultConfig {
+ versionCode getVersionCode()
+ …
+ }
+}
+</pre>
+
+<p>This example shows how to append <em>debug</em> to your package and version names used in the
+<code>debug</code> build variant of your app: </p>
+
+<pre>
+android {
+ buildTypes {
+ debug {
+ packageNameSuffix ‘.debug’
+ versionNameSuffix ‘-DEBUG’
+ }
+ beta {
+ …
+ }
+ }
+}
+</pre>
+
+
+<p>You can also use the declarative DSL in the Android build system to generate custom build
+versions, for example a debuggable version of your release APK. This examples adds the
+<code>debuggable true</code> property to the <code>release</code> build type in the
+<code>build.gradle</code> file to build an identical debuggable version of the release package. </p>
+
+<pre>
+android {
+ buildTypes {
+ debugRelease.initWith(buildTypes.release)
+ debugRelease {
+ debuggable true
+ packageNameSuffix &#39;.debugrelease&#39;
+ signingConfig signingConfigs.debug
+ }
+
+ }
+ sourceSets.debugRelease.setRoot(&#39;src/release&#39;)
+}
+</pre>
+
+
+
+
+
+
+<h2 id="debug-inspect">Debugging and Code Inspections</h2>
+<p>Using code inspection tools such as <a href="{@docRoot}tools/help/lint.html">lint</a> is a
+standard part of Android development. Android Studio extends
+<a href="{@docRoot}tools/help/lint.html">lint</a> support with additional
+<a href="{@docRoot}tools/help/lint.html">lint</a> checks and supports Android
+<a href="{@docRoot}tools/debugging/annotations.html">annotations</a> that
+allow you to help detect more subtle code problems, such as null pointer exceptions and resource
+type conflicts. Annotations are added as metadata tags that you attach to variables, parameters,
+and return values to inspect method return values, passed parameters, and local variables and
+fields. </p>
+
+<p>For more information on enabling <a href="{@docRoot}tools/help/lint.html">lint</a> inspections
+and running <a href="{@docRoot}tools/help/lint.html">lint</a>,
+see <a href="{@docRoot}tools/debugging/improving-w-lint.html">Improving Your Code with lint</a>.
+For more information about using annotations, see
+<a href="{@docRoot}tools/debugging/annotations.html#annotations">Improving your Code with
+Annotations</a>. </p>
+
+<p>In addition to code inspection, Android Studio provides an integrated
+<a href="{@docRoot}tools/studio/index.html#mem-cpu">memory and CPU monitor</a> view so you
+can more easily monitor your app's performance and memory usage to track CPU usage, find
+deallocated objects, locate memory leaks, and track the amount of memory the connected device is
+using. </p>
+
+
+
+<h2 id="resource-optimization">Resource Optimization </h2>
+<p>After importing and building your app, Android Studio supports several
+<a href="http://www.gradle.org">Gradle</a>-based properties to help you minimize your app's
+resource utilization. </p>
+
+
+<h3>Resource shrinking</h3>
+<p>In Android Studio, resource shrinking enables the automatic removal of unused resources from
+your packaged app and also removes resources from library dependencies if the resources are not
+actually used by your app.</p>
+
+<p>Use the <code>shrinkResources</code> attribute in the <code>buildType</code> block in your
+<code>build.gradle</code> file to enable resource shrinking. For example, if your application is
+using <a href="{@docRoot}google/play-services/index.html">Google Play services</a>
+to access Google Drive functionality, and you are not currently using
+<a href="{@docRoot}google/play-services/plus.html">Google+ Sign In</a>, then
+this setting removes the various drawable assets for the <code>SignInButton</code> buttons. </p>
+
+<p class="note"><strong>Note:</strong> Resource shrinking works in conjunction with code shrinking
+tools, such as <a href="{@docRoot}tools/help/proguard.html">ProGuard</a>. </p>
+
+<p>To enable resource shrinking, update the <code>buildTypes</code> block in the
+<code>build.gradle</code> file to include <code>minifyEnabled true</code>,
+<code>shrinkResources true</code>, and <code>proguardFiles</code> settings as shown in the
+following example <a href="http://www.gradle.org">Gradle</a> build file.</p>
+
+<pre>
+android {
+ ...
+
+ buildTypes {
+ release {
+ minifyEnabled true
+ shrinkResources true
+ proguardFiles getDefaultProguardFile('proguard-android.txt'),
+ 'proguard-rules.pro'
+ }
+ }
+}
+</pre>
+
+
+
+<h3>Filtering language resources</h3>
+<p>Use the <code>resConfig</code> attribute in your <code>build.gradle</code> file
+to filter the locale resources included in your packaged app. This filtering can be especially
+useful when library dependencies such as <code>appcompat-v7</code> and other libraries such as
+<code>google-play-services_lib</code> are included in your app. </p>
+
+<p>The following example limits the locale resources to three language settings: <code>en</code>,
+<code>de</code>, and <code>es</code>:</p>
+
+<pre>
+apply plugin: 'android'
+
+android {
+ compileSdkVersion 22
+ buildToolsVersion "22.0.1"
+
+ defaultConfig {
+ minSdkVersion 8
+ targetSdkVersion 22
+ versionCode 1
+ versionName "1.0"
+ resConfigs "en", "de", "es" //Define the included language resources.
+ }
+...
+
+</pre>
+
+
+
+<h4>Filtering bundled resources</h4>
+<p>You can also use the <code>resConfig</code> build setting to limit the bundled resources
+in any resource folder. For example, you could also add <code>resConfigs</code>
+settings for density folders, such as <code>mdpi</code> or <code>hdpi</code> to limit the drawable
+resources that are packaged in your <code>APK</code> file. This example limits the app's
+bundled resources to medium-density (MDPI) and high-density (HDPI) resources. </p>
+
+<pre>
+android {
+ defaultConfig {
+ ...
+ resConfigs "mdpi", "hdpi"
+ }
+}
+</pre>
+
+For more information about screen and resource densities, see
+<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>
+and <a href="{@docRoot}training/multiscreen/screendensities.html">Supporting Different Densities</a>.
+
+
+<h3>Resource merging </h3>
+<p>With Android Studio, identical resources, such as copies of launcher and menu icons, may end up
+in different resource folders throughout your app. To reduce resource duplication and improve
+the performance of your app, Android Studio merges resources with an identical resource name, type,
+and qualifier into a single resource and passes the single, merged resource to the Android Asset
+Packaging Tool (AAPT) for distribution in the APK file. </p>
+
+<p>The resource merging process looks for identical resources in the following <code>/res/</code>
+folders: </p>
+<ul>
+ <li>AAR bundles of library project dependencies</li>
+ <li><code>src/main/</code> </li>
+ <li><code>src/<em>productFlavor</em>/</code> </li>
+ <li><code>src/<em>buildType</em>/</code> </li>
+</ul>
+
+<p>Identical resources are merged in the following low to high priority order: </p>
+<pre>
+dependencies --> src/main/ --> src/productFlavor/ --> src/buildType/
+</pre>
+
+<p>For example, if the <code>res/ic_menu.png</code> file is included in both the
+<code>src/main/res/</code> and <code>src/productFlavor/res/</code> folders, the resources are merged
+so only the file with the higher priority, in this case the <code>src/productFlavor/res/</code>
+file, is included in the APK file. </p>
+
+<p class="note"><strong>Note:</strong> Identical resources in the same source set are not merged
+and instead generate a resource merge error. This can happen if the <code>sourceSet</code> property
+in the <code>build.gradle</code> file is used to define multiple source sets, for example
+<code>src/main/res/</code> and <code>src/main/res2/</code>, and these folders contain identical
+resources. </p>
+
+
+
+
+<h2 id="signing">App Signing and ProGuard </h2>
+<p>Based on the imported Eclipse ADT app settings, Android Studio automatically sets up your app
+signing and maintains any ProGuard settings. </p>
+
+<h3>App Signing</h3>
+<p>If your app used a debug certificate in Eclipse ADT, Android Studio continues to reference that
+certificate. Otherwise, the <code>debug</code> configuration uses the Android Studio generated
+debug keystore, with a known password and a default key with a known password located in
+<code>$HOME/.android/debug.keystore</code>. The <code>debug</code> build type is set to use this
+debug <code>SigningConfig</code> automatically when you run or debug your project
+from Android Studio. </p>
+
+<p>In release mode, Android Studio applies the release certificate used in Eclipse ADT. If no
+release certificate was located during the import process, add the release signing configuration to
+the <code>build.gradle</code> file or use the <strong> Build > Generate Signed APK</strong> menu
+option to open the Generate Signed APK Wizard. For more information about signing your app, see
+<a href="{@docRoot}tools/publishing/app-signing.html">Signing Your Applications</a>. </p>
+
+
+<h3>ProGuard</h3>
+<p>If the <a href="{@docRoot}tools/help/proguard.html">ProGuard</a> option is specified in the
+<code>project.properties</code> file in the Eclipse ADT project, Android Studio imports the
+<a href="{@docRoot}tools/help/proguard.html">ProGuard</a> files and adds the
+<a href="{@docRoot}tools/help/proguard.html">ProGuard</a> settings to the
+<code>build.gradle</code> file. <a href="{@docRoot}tools/help/proguard.html">ProGuard</a> is
+supported through the <code>minifyEnabled</code> property as shown in this example. </p>
+
+<pre>
+android {
+ buildTypes {
+ release {
+ minifyEnabled true
+ proguardFile getDefaultProguardFile(&#39;proguard-android.txt&#39;)
+ }
+ }
+
+ productFlavors {
+ flavor1 {
+ }
+ flavor2 {
+ proguardFile &#39;some-other-rules.txt&#39;
+ }
+ }
+}
+
+</pre></p>
+
+
+
+
+<h2 id="support-lib">Android Support Repository and Google Play services Repository</h2>
+<p>While Eclipse ADT uses the Android <a href="{@docRoot}tools/support-library/index.html">Support
+Library</a> and Google Play services Library, Android Studio replaces these libraries during the
+import process with the Android Support Repository and Google Repository to maintain
+compatible functionality and support new Android features. Android Studio adds these dependencies
+as Maven dependencies using the known Maven coordinates, so these dependencies do not require
+manual updates. </p>
+
+<p>In Eclipse, in order to use a
+<a href="{@docRoot}tools/support-library/index.html">Support Library</a>, you must modify your
+project's classpath dependencies within your development environment for each
+<a href="{@docRoot}tools/support-library/index.html">Support Library</a> you want to use. In
+Android Studio, you no longer need to copy library sources into your
+own projects, you can simply declare a dependency and the library is automatically downloaded and
+merged into your project. This includes automatically merging in resources, manifest entries,
+<a href="{@docRoot}tools/help/proguard.html">ProGuard</a> exclusion rules, and custom lint rules
+at build time. </p>
+
+<p>Android Studio also supports binary library Android ARchives (AARs). AARs are a library project's
+main output as a combination of compiled code (as a jar file and/or native .so files) and
+resources (manifest, res, assets). <p/>
+
+
+<h2 id="app-package">App Packaging</h2>
+<p>The Android build system introduces the use of the <code>applicationId</code> attribute to
+uniquely identify application packages for publishing. The application ID is set in the
+<code>android</code> section of the <code>build.gradle</code> file. </p>
+
+<p>The <code>applicationId</code> is specified only in your <code>build.gradle</code> file, and
+not in the
+<code>AndroidManifest.xml</code> file. The Gradle-based build system enables you
+to uniquely identify different packages for each build variant based on product flavors and build
+types. You can also add the <code>applicationIdSuffix</code> property to the build type in the
+<code>build.gradle</code> file to append an identifier, such as '.debug', to the application ID
+generated for each product flavor. </p>
+
+
+
+<h2 id="software-updates">Software Updates</h2>
+<p>Android Studio provides several levels of update and maintenance to help you keep Android Studio
+up-to-date based on your code-level preference: </p>
+
+<ul>
+ <li><strong>Canary channel</strong>: Canary builds provide bleeding edge releases and are updated
+ about weekly. These builds do get tested, but are still subject to bugs, as these are
+ early releases. This is not recommended for production.</li>
+ <li><strong>Dev channel</strong>: Dev builds are canary builds that passed initial testing and
+ usage. They are updated roughly bi-weekly or monthly.</li>
+ <li><strong>Beta channel</strong>: Beta builds provide beta-quality releases for final testing
+ and feedback before a production release.</li>
+ <li><strong>Stable channel</strong>: Stable builds provide stable, production-ready release
+ versions.</li>
+</ul>
+
+
+
+<h2 id="version-control">Version Control </h2>
+<p>Eclipse ADT supports version control through the use of plugins, such as the EGit and Subversive
+plug-ins. </p>
+
+<p>Android Studio supports a variety of version control systems (Git, GitHub, CVS, Mercurial,
+Subversion, and Google Cloud) so version control operations can continue from within Android
+Studio. </p>
+
+<p>After importing your Eclipse ADT app into Android Studio, use the
+Android Studio <em>VCS</em> menu options to enable VCS support for the desired version control
+system, create a repository, import the new files into version control, and perform other version
+control operations. </p>
+
+<p class="note"><strong>Note:</strong> You can also use the
+<strong>File &gt; Setting &gt; Version Control</strong> menu option to setup and modify the version
+control settings. </p>
+
+<h3>Files to ignore </h3>
+<p>A number of Android Studio files are typically not added to version control as these are
+temporary files or files that get overwritten with each build. These files are listed in
+an exclusion file, such as <code>.gitignore</code>, for the project and each app module.
+Typically, the following files are excluded from version control: </p>
+
+<ul>
+ <li>.gradle </li>
+ <li>/local.properties </li>
+ <li>/.idea/workspace.xml </li>
+ <li>/.idea/libraries </li>
+ <li>.DS_Store</li>
+ <li>/build </li>
+ <li>/captures </li>
+</ul>
diff --git a/docs/html/tools/studio/index.jd b/docs/html/tools/studio/index.jd
index 0113347..5041b83 100644
--- a/docs/html/tools/studio/index.jd
+++ b/docs/html/tools/studio/index.jd
@@ -12,9 +12,6 @@ page.tags=studio,sdk,tools,firstapp
<li><a href="#project-structure">Project and File Structure</a></li>
<li><a href="#build-system">Android Build System</a></li>
<li><a href="#debug-perf">Debug and Performance</a></li>
- <li><a href="#install-updates">Installation, Setup, and Update Management</a></li>
- <li><a href="#proxy">HTTP Proxy Settings</a></li>
- <li><a href="#other">Other Highlights</a></li>
</ol>
@@ -46,7 +43,6 @@ Android Studio offers:</p>
<li>And much more</li>
</ul>
-<p><b><a href="{@docRoot}sdk/index.html">Download Android Studio now</a></b>. </p>
<p>If you're new to Android Studio or the IntelliJ IDEA interface, this
page provides an introduction to some key Android
@@ -104,6 +100,7 @@ representation. To switch to back to the segregated project view, select <strong
from the <strong>Project</strong> drop-down. </p>
+
<h3 id="other-views">Other Android Studio views</h3>
<p>When you use the <em>Project</em> view in Android Studio, you
should notice that the project structure appears different than you may be used to in Eclipse. Each
@@ -140,22 +137,7 @@ and <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>.</p>
-<h3>Creating new files</h3>
-<p>You can quickly add new code and resource files by clicking the appropriate directory in the
-<strong>Project</strong> pane and pressing <code>ALT + INSERT</code> on Windows and Linux or
-<code>COMMAND + N</code> on Mac. Based on the type of directory selected, Android Studio
-offers to create the appropriate file type.</p>
-
-<p>For example, if you select a layout directory, press <code>ALT + INSERT</code> on Windows,
-and select <strong>Layout resource file</strong>, a dialog opens so you can name the file
-(you can exclude the {@code .xml} suffix) and choose a root view element. The editor then
-switches to the layout design editor so you can begin designing your layout.</p>
-
-
-
<h2 id="build-system">Android Build System</h2>
-
-<h3>Android Build System</h3>
<p>The Android build system is the toolkit you use to build, test, run and package
your apps. This build system replaces the Ant system used with Eclipse ADT. It can run as an
integrated tool from the Android Studio menu and independently from the command line. You can use
@@ -175,76 +157,11 @@ To configure custom build settings in an Android Studio project, see
<a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a>.</p>
-<h3>Application ID for package identification </h3>
-<p>With the Android build system, the <em>applicationId</em> attribute is used to
-uniquely identify application packages for publishing. The application ID is set in the
-<em>android</em> section of the <code>build.gradle</code> file.
-</p>
-
- <pre>
- apply plugin: 'com.android.application'
-
- android {
- compileSdkVersion 19
- buildToolsVersion "19.1"
-
- defaultConfig {
- <strong>applicationId "com.example.my.app"</strong>
- minSdkVersion 15
- targetSdkVersion 19
- versionCode 1
- versionName "1.0"
- }
- ...
- </pre>
-
-<p class="note"><strong>Note:</strong> The <em>applicationId</em> is specified only in your
-{@code build.gradle} file, and not in the AndroidManifest.xml file.</p>
-
-<p>When using build variants, the build system enables you to uniquely identify different
-packages for each product flavors and build types. The application ID in the build type is added as
-a suffix to those specified for the product flavors. </p>
-
- <pre>
- productFlavors {
- pro {
- applicationId = "com.example.my.pkg.pro"
- }
- free {
- applicationId = "com.example.my.pkg.free"
- }
- }
-
- buildTypes {
- debug {
- applicationIdSuffix ".debug"
- }
- }
- ....
- </pre>
-
-<p>The package name must still be specified in the manifest file. It is used in your source code
-to refer to your R class and to resolve any relative activity/service registrations. </p>
-
- <pre>
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- <strong>package="com.example.app"</strong>
- </pre>
-
-<p class="note"><strong>Note:</strong> If you have multiple manifests (for example, a product
-flavor specific manifest and a build type manifest), the package name is optional in those manifests.
-If it is specified in those manifests, the package name must be identical to the package name
-specified in the manifest in the <code>src/main/</code> folder. </p>
-
-<p>For more information about the build files and process, see
-<a href="{@docRoot}sdk/installing/studio-build.html">Build System Overview</a>.</p>
-
-
-
<h2 id="debug-perf">Debug and Performance</h2>
-
+<p>Android Studio provides a number of improvements to assist you in debugging and improving the
+performance of your code, including an improved virtual device management, inline debugging, and
+performance analysis tools.</p>
<h3>Android Virtual Device (AVD) Manager</h3>
<p>AVD Manager has updated screens with links to help you select the most popular device
@@ -349,7 +266,8 @@ android {
<p>You can also manage inspection profiles and configure inspections within Android Studio.
-Choose <strong>File &gt; Settings &gt; Project Settings</strong> and expand <strong>Editor</strong>.
+Choose <strong>File &gt; Settings &gt;</strong>, expand the <strong>Editor</strong> options,
+and select <strong>Inspections</strong>.
The <em>Inspection Configuration</em> page appears with the supported inspections.</p>
<p><img src="{@docRoot}images/tools/studio-inspections-config.png" alt="" /> </p>
<p class="img-caption"><strong>Figure 5.</strong> Configure inspections.</p>
@@ -505,7 +423,7 @@ the device display. </p>
<h3>Log messages</h3>
<p>When you build and run your app with Android Studio, you can view adb and device log messages
-(logcat) in the DDMS pane by clicking <strong>Android</strong> at the bottom of the window.</p>
+(logcat) by clicking <strong>Android</strong> at the bottom of the window.</p>
<p>If you want to debug your app with the
<a href="{@docRoot}tools/help/monitor.html">Android Debug Monitor</a>, you can launch it by
@@ -519,231 +437,4 @@ controlling device behaviors, and more. It also includes the Hierarchy Viewer to
-<h2 id="install-updates">Installation, Setup, and Update Management</h2>
-
-<h3>Android Studio installation and setup wizards</h3>
-<p>When you begin the installation process, an installation and setup wizard walks you through
-a step-by-step installation and setup process as the wizard checks for system requirements,
-such as the Java Development Kit (JDK) and available RAM, and then prompts for optional
-installation options, such as the Intel&#174; HAXM emulator accelerator.</p>
-
-<p>During the installation process, a setup wizard walks you through the setup processes as
-the wizard updates your system image and emulation requirements, such GPU, and then creates
-an optimized default Android Virtual Device (AVD) based on Android 5 (Lollipop) for speedy and
-reliable emulation. </p>
-<p><img src="{@docRoot}images/tools/studio-setup-wizard.png" /></p>
-<p class="img-caption"><strong>Figure 9.</strong> Installation and setup wizard.</p>
-
-
-<h3>Expanded template and form factor support</h3>
-<p>Android Studio supports templates for Google Services and expands the available device
-types. </p>
-
- <h4> Android Wear and TV support</h4>
- <p>For easy cross-platform development, the Project Wizard provides templates for
- creating your apps for Android Wear and TV. </p>
- <p><img src="{@docRoot}images/tools/studio-tvwearsupport.png" />
-
- <p class="img-caption"><strong>Figure 10.</strong> Supported form factors.</p>
- <p>During app creation, the Project Wizard also displays an API Level dialog to help you choose
- the best <em>minSdkVersion</em> for your project.</p>
-
-
- <h4> Google App Engine integration (Google Cloud Platform/Messaging)</h4>
- <p>Quick cloud integration. Using Google App Engine to connect to the Google cloud
- and create a cloud end-point is as easy as selecting <em>File > New Module > App Engine Java
- Servlet Module</em> and specifying the module, package, and client names. </p>
- <p><img src="{@docRoot}images/tools/studio-cloudmodule.png" /></p>
- <p class="img-caption"><strong>Figure 11.</strong> Google App Engine integration.</p>
-
-
-<h3>Easy access to project and file settings</h3>
-<p>Android Studio provides setting dialogs so you can manage the most important project and file
-settings from the <strong>File</strong> menus as well as the build and configuration files. For
-example, you can use the <strong>File &gt; Project Structure</strong> menu or
-the <code>build.gradle</code> file to update your <code>productFlavor</code> settings.
-Additional settings from the <strong>File</strong> menus include:
-<ul>
- <li>SDK and JDK location </li>
- <li>SDK version </li>
- <li>Gradle and Android Plugin for Gradle versions </li>
- <li>Build tools version </li>
- <li>Multidex setting</li>
- <li>Product flavors </li>
- <li>Build types </li>
- <li>Dependencies </li>
-</ul>
-</p>
-
-
-
-<h3>Update channels</h3>
-<p>Android Studio provides four update channels to keep Android Studio up-to-date based on your
-code-level preference:
-<ul>
- <li><strong>Canary channel</strong>: Canary builds provide bleeding edge releases, updated
- about weekly. While these builds do get tested, they are still subject to bugs, as we want
- people to see what's new as soon as possible. This is not recommended for production.</li>
- <li><strong>Dev channel</strong>: Dev builds are hand-picked older canary builds that survived
- the test of time. They are updated roughly bi-weekly or monthly.</li>
- <li><strong>Beta channel</strong>: Beta builds are used for beta-quality releases before a
- production release.</li>
- <li><strong>Stable channel</strong>: Used for stable, production-ready versions.</li>
-</ul>
-</p>
-
-<p>By default, Android Studio uses the <em>Stable</em> channel. Use
-<strong>File > Settings > Updates</strong> to change your channel setting. </p>
-
-
-
-<h2 id="proxy">Proxy Settings</h2>
-<p>Proxies serve as intermediary connection points between HTTP clients and web servers that add
-security and privacy to internet connections.</p>
-
-<p>To support running Android Studio behind a firewall, set the proxy settings for the
-Android Studio IDE and the SDK Manager. Use the Android Studio IDE HTTP Proxy settings page to set
-the HTTP proxy settings for Android Studio. The SDK Manager has a separate HTTP Proxy settings
-page.</p>
-
-<p>When running the Android Plugin for Gradle from the command line or on machines where
-Android Studio is not installed, such as continuous integration servers, set the proxy settings
-in the Gradle build file.</p>
-
-<p class="note"><strong>Note:</strong> After the initial installation of the Android Studio bundle,
-Android Studio can run with internet access or off-line. However, Android Studio requires an
-internet connection for Setup Wizard synchronization, 3rd-party library access, access to remote
-repositories, Gradle initialization and synchronization, and Android Studio version updates.</p>
-
-
-<h3>Setting up the Android Studio Proxy</h3>
-<p>Android Studio supports HTTP proxy settings so you can run Android Studio behind a firewall or
-secure network. To set the HTTP proxy settings in Android Studio:</p>
-<ol>
- <li>From the main menu choose <strong>File &gt; Settings &gt; Appearance & Behavior -- System
- Settings -- HTTP Proxy</strong>.
-
-<li>In Android Studio, open the IDE Settings dialog.
- <ul>
- <li>On Windows and Linux, choose
- <strong>File &gt; Settings &gt; IDE Setting -- HTTP Proxy</strong>. </li>
- <li>On Mac, choose
- <strong>Android Studio &gt; Preferences &gt; IDE Setting -- HTTP Proxy</strong>. </li>
- </ul>
- The HTTP Proxy page appears.</li>
- <li>Select <strong>auto-detection</strong> to use an auto-configuration URL to configure the
- proxy settings or <strong>manual</strong> to enter each of the settings. For a detailed explanation
- of these settings, see
- <a href="https://www.jetbrains.com/idea/help/http-proxy.html">HTTP Proxy</a>. </li>
- <li>Click <strong>Apply</strong> to enable the proxy settings. </li>
-</ol>
-
-<h3>Android Plugin for Gradle HTTP proxy settings</h3>
-When running the Android Plugin from the command line or on machines where Android Studio is not
-installed, set the Android Plugin for Gradle proxy settings in the Gradle build file.</p>
-
-<p>For application-specific HTTP proxy settings, set the proxy settings in the
-{@code build.gradle} file as required for each application module.</p>
-<pre>
-apply plugin: 'com.android.application'
-
-android {
- ...
-
- defaultConfig {
- ...
- systemProp.http.proxyHost=proxy.company.com
- systemProp.http.proxyPort=443
- systemProp.http.proxyUser=userid
- systemProp.http.proxyPassword=password
- systemProp.http.auth.ntlm.domain=domain
- }
- ...
-}
-</pre>
-
-
-
-<p>For project-wide HTTP proxy settings, set the proxy settings in the
-<code>gradle/gradle.properties</code> file. </p>
-
-<pre>
-# Project-wide Gradle settings.
-...
-
-systemProp.http.proxyHost=proxy.company.com
-systemProp.http.proxyPort=443
-systemProp.http.proxyUser=username
-systemProp.http.proxyPassword=password
-systemProp.http.auth.ntlm.domain=domain
-
-systemProp.https.proxyHost=proxy.company.com
-systemProp.https.proxyPort=443
-systemProp.https.proxyUser=username
-systemProp.https.proxyPassword=password
-systemProp.https.auth.ntlm.domain=domain
-
-...
-</pre>
-
-
-<p>For information about using Gradle properties for proxy settings, see the
- <a href="http://www.gradle.org/docs/current/userguide/build_environment.html">Gradle User Guide</a>.</p>
-
-<p class="note"><strong>Note:</strong> When using Android Studio, the settings in the Android
-Studio IDE HTTP proxy settings page override the HTTP proxy settings in the
-<strong>gradle.properties</strong> file.</p>
-
-
-
-<h3>SDK Manager HTTP Proxy Settings </h3>
-<p>SDK Manager proxy settings enable proxy internet access for Android package and library
-updates from SDK Manager packages. </p>
-
-<p>To set the SDK Manager settings for proxy internet access, start the SDK Manager and open the
-SDK Manager page. </p>
-
-<ul>
- <li>On Windows, select <strong>Tools &gt; Options</strong> from the menu bar. </li>
- <li>On Mac and Linux, choose <strong>Tools &gt; Options</strong> from the system menu bar. </li>
- </ul>
-
-<p>The Android SDK Manager page appears. Enter the settings and click <strong>Apply</strong>. </p>
-
-
-
-<h2 id="other">Other Highlights</h2>
-
-<h3 id="trans-editor"> Translations Editor</h3>
-<p>Multi-language support is enhanced with the Translations Editor plugin so you can easily add
-a variety of locales to the app's translation file. With
-<a href="https://tools.ietf.org/html/bcp47">BCP 47</a> support, the editor combines language and
-region codes into a single selection for targeted localizations. Color codes indicate whether a
-locale is complete or still missing string translations. </p>
-
-<p>To access the Translations Editor, open a <code>strings.xml</code> file and click the
-<strong>Open Editor</strong> link. </p>
-
- <img src="{@docRoot}images/tools/studio-translationeditoropen.png" />
- <p class="img-caption"><strong>Figure 12.</strong> Add locales and strings in the
- Translations Editor.</p>
-
-
-<h3> Editor support for the latest Android APIs</h3>
-<p>Android Studio supports the
-<a href="{@docRoot}design/material/index.html">Material Design</a></li> themes, widgets, and
-graphics, such as shadow layers and API version rendering (showing the layout across different
-UI versions). Also, the drawable XML tags and attributes, such as <code>&lt;ripple&gt;</code>
-and <code>&lt;animated-selector&gt;</code>, are supported.</p>
-
-
-<h3 id="git-samples"> Easy access to Android code samples on GitHub</h3>
-<p>Clicking <strong>Import Samples</strong> from the <strong>File</strong> menu or <em>Welcome</em>
-page provides seamless access to Google code samples on GitHub.</p>
- <p><img src="{@docRoot}images/tools/studio-samples-githubaccess.png" /></p>
- <p class="img-caption"><strong>Figure 13.</strong> Get code samples from GitHub.</p>
-
- <p><img src="{@docRoot}images/tools/studio-sample-in-editor.png" /></p>
- <p class="img-caption"><strong>Figure 14.</strong> Imported code sample.</p>
-
diff --git a/docs/html/tools/studio/studio-config.jd b/docs/html/tools/studio/studio-config.jd
new file mode 100644
index 0000000..f9646b8
--- /dev/null
+++ b/docs/html/tools/studio/studio-config.jd
@@ -0,0 +1,174 @@
+page.title=Configuration
+page.metaDescription=Learn about the Android Studio configuration.
+page.tags=studio, configuration
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#update-channel">Update Channels</a></li>
+ <li><a href="#proxy">Proxy Settings</a></li>
+ </ol>
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}sdk/installing/index.html?pkg=studio">Installing Android Studio</a></li>
+ <li><a href="{@docRoot}tools/workflow/index.html">Workflow</a></li>
+ <li><a href="{@docRoot}sdk/installing/studio-features.html">Build System</a></li>
+ </ol>
+
+</div>
+</div>
+
+
+<p>During installation, Android Studio provides wizards and templates that verify your system
+requirements, such as the Java Development Kit (JDK) and available RAM, and configure default
+settings, such as an optimized default Android Virtual Device (AVD) emulation and updated system
+images. This document describes additional configuration settings you may want to use to
+customize your use of Android Studio. </p>
+
+<p>For specific documentation about emulator and device setup and use, see
+<a href="{@docRoot}tools/devices/index.html">Managing Virtual Devices</a>,
+<a href="{@docRoot}tools/device.html">Using Hardware Devices</a>, and
+<a href="{@docRoot}tools/extras/oem-usb.html">OEM USB Drivers</a>. </p>
+
+
+
+<h2 id="update-channel">Update channels</h2>
+<p>Android Studio provides four update channels to keep Android Studio up-to-date based on your
+code-level preference:
+<ul>
+ <li><strong>Canary channel</strong>: Canary builds provide bleeding edge releases, updated
+ about weekly. While these builds do get tested, they are still subject to bugs, as we want
+ people to see what's new as soon as possible. This is not recommended for production.</li>
+ <li><strong>Dev channel</strong>: Dev builds are hand-picked older canary builds that survived
+ the test of time. They are updated roughly bi-weekly or monthly.</li>
+ <li><strong>Beta channel</strong>: Beta builds are used for beta-quality releases before a
+ production release.</li>
+ <li><strong>Stable channel</strong>: Used for stable, production-ready versions.</li>
+</ul>
+</p>
+
+<p>By default, Android Studio uses the <em>Stable</em> channel. Use
+<strong>File > Settings > Appearance & Behavior System Settings > Updates</strong> to change your
+channel setting. </p>
+
+
+
+<h2 id="proxy">Proxy Settings</h2>
+<p>Proxies serve as intermediary connection points between HTTP clients and web servers that add
+security and privacy to internet connections.</p>
+
+<p>To support running Android Studio behind a firewall, set the proxy settings for the
+Android Studio IDE and the SDK Manager. Use the Android Studio IDE HTTP Proxy settings page to set
+the HTTP proxy settings for Android Studio. The SDK Manager has a separate HTTP Proxy settings
+page.</p>
+
+<p>When running the Android Plugin for Gradle from the command line or on machines where
+Android Studio is not installed, such as continuous integration servers, set the proxy settings
+in the Gradle build file.</p>
+
+<p class="note"><strong>Note:</strong> After the initial installation of the Android Studio bundle,
+Android Studio can run with internet access or off-line. However, Android Studio requires an
+internet connection for Setup Wizard synchronization, 3rd-party library access, access to remote
+repositories, Gradle initialization and synchronization, and Android Studio version updates.</p>
+
+
+<h3>Setting up the Android Studio Proxy</h3>
+<p>Android Studio supports HTTP proxy settings so you can run Android Studio behind a firewall or
+secure network. To set the HTTP proxy settings in Android Studio:</p>
+<ol>
+ <li>From the main menu choose <strong>File &gt; Settings &gt; Appearance & Behavior -- System
+ Settings -- HTTP Proxy</strong>.
+
+<li>In Android Studio, open the IDE Settings dialog.
+ <ul>
+ <li>On Windows and Linux, choose
+ <strong>File &gt; Settings &gt; IDE Setting -- HTTP Proxy</strong>. </li>
+ <li>On Mac, choose
+ <strong>Android Studio &gt; Preferences &gt; IDE Setting -- HTTP Proxy</strong>. </li>
+ </ul>
+ The HTTP Proxy page appears.</li>
+ <li>Select <strong>auto-detection</strong> to use an auto-configuration URL to configure the
+ proxy settings or <strong>manual</strong> to enter each of the settings. For a detailed explanation
+ of these settings, see
+ <a href="https://www.jetbrains.com/idea/help/http-proxy.html">HTTP Proxy</a>. </li>
+ <li>Click <strong>Apply</strong> to enable the proxy settings. </li>
+</ol>
+
+<h3>Android Plugin for Gradle HTTP proxy settings</h3>
+When running the Android Plugin from the command line or on machines where Android Studio is not
+installed, set the Android Plugin for Gradle proxy settings in the Gradle build file.</p>
+
+<p>For application-specific HTTP proxy settings, set the proxy settings in the
+{@code build.gradle} file as required for each application module.</p>
+<pre>
+apply plugin: 'com.android.application'
+
+android {
+ ...
+
+ defaultConfig {
+ ...
+ systemProp.http.proxyHost=proxy.company.com
+ systemProp.http.proxyPort=443
+ systemProp.http.proxyUser=userid
+ systemProp.http.proxyPassword=password
+ systemProp.http.auth.ntlm.domain=domain
+ }
+ ...
+}
+</pre>
+
+
+
+<p>For project-wide HTTP proxy settings, set the proxy settings in the
+<code>gradle/gradle.properties</code> file. </p>
+
+<pre>
+# Project-wide Gradle settings.
+...
+
+systemProp.http.proxyHost=proxy.company.com
+systemProp.http.proxyPort=443
+systemProp.http.proxyUser=username
+systemProp.http.proxyPassword=password
+systemProp.http.auth.ntlm.domain=domain
+
+systemProp.https.proxyHost=proxy.company.com
+systemProp.https.proxyPort=443
+systemProp.https.proxyUser=username
+systemProp.https.proxyPassword=password
+systemProp.https.auth.ntlm.domain=domain
+
+...
+</pre>
+
+
+<p>For information about using Gradle properties for proxy settings, see the
+ <a href="http://www.gradle.org/docs/current/userguide/build_environment.html">Gradle User Guide</a>.</p>
+
+<p class="note"><strong>Note:</strong> When using Android Studio, the settings in the Android
+Studio IDE HTTP proxy settings page override the HTTP proxy settings in the
+<strong>gradle.properties</strong> file.</p>
+
+
+
+<h3>SDK Manager HTTP Proxy Settings </h3>
+<p>SDK Manager proxy settings enable proxy internet access for Android package and library
+updates from SDK Manager packages. </p>
+
+<p>To set the SDK Manager settings for proxy internet access, start the SDK Manager and open the
+SDK Manager page. </p>
+
+<ul>
+ <li>On Windows, select <strong>Tools &gt; Options</strong> from the menu bar. </li>
+ <li>On Mac and Linux, choose <strong>Tools &gt; Options</strong> from the system menu bar. </li>
+ </ul>
+
+<p>The Android SDK Manager page appears. Enter the settings and click <strong>Apply</strong>. </p>
+
+
+
diff --git a/docs/html/tools/studio/studio-features.jd b/docs/html/tools/studio/studio-features.jd
new file mode 100644
index 0000000..76eba10
--- /dev/null
+++ b/docs/html/tools/studio/studio-features.jd
@@ -0,0 +1,123 @@
+page.title=Features
+page.metaDescription=Learn about the Android Studio features.
+page.tags=studio, features
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#trans-editor">Translations Editor</a></li>
+ <li><a href="#git-samples">Android Code Samples on GitHub</a></li>
+ <li><a href="#template-support">Expanded Template and Form Factor Support</a></li>
+ <li><a href="#project-settings">Android Studio and Project Settings</a></li>
+ <li><a href="#support-apis">Editor Support for the Latest Android APIs</a></li>
+ </ol>
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}tools/workflow/index.html">Workflow</a></li>
+ <li><a href="{@docRoot}sdk/installing/studio-build.html">Build System</a></li>
+ <li><a href="{@docRoot}sdk/installing/studio-tips.html">Android Studio Tip & Tricks</a></li>
+ </ol>
+
+</div>
+</div>
+
+
+<p>If you're new to Android Studio or exploring recent updates, this
+page provides an introduction to some key Android Studio features.</p>
+
+<p>For specific Android Studio how-to documentation, see the pages in the <a href=
+"{@docRoot}tools/workflow/index.html">Workflow</a> section, such as
+<a href="{@docRoot}sdk/installing/create-project.html">Managing Projects from Android Studio</a>
+and
+<a href="{@docRoot}tools/building/building-studio.html">Building and Running from Android Studio</a>. </p>
+
+
+
+<h2 id="trans-editor">Translations Editor</h2>
+<p>Multi-language support is enhanced with the Translations Editor plugin so you can easily add
+a variety of locales to the app's translation file. With
+<a href="https://tools.ietf.org/html/bcp47">BCP 47</a> support, the editor combines language and
+region codes into a single selection for targeted localizations. Color codes indicate whether a
+locale is complete or still missing string translations. </p>
+
+<p>To access the Translations Editor, open a <code>strings.xml</code> file and click the
+<strong>Open Editor</strong> link, or click the globe icon
+(<img src="{@docRoot}images/tools/studio-globe-icon.png" style="vertical-align:bottom;margin:0;height:19px" />) in the Design layout view. </p>
+
+
+ <img src="{@docRoot}images/tools/studio-translationeditoropen.png" />
+ <p class="img-caption"><strong>Figure 1.</strong> Add locales and strings in the
+ Translations Editor.</p>
+
+
+
+<h2 id="git-samples">Android Code Samples on GitHub</h2>
+<p>Clicking <strong>Import Samples</strong> from the <strong>File</strong> menu or <em>Welcome</em>
+page provides seamless access to Google code samples on GitHub.</p>
+ <p><img src="{@docRoot}images/tools/studio-samples-githubaccess.png" /></p>
+ <p class="img-caption"><strong>Figure 2.</strong> Get code samples from GitHub.</p>
+
+
+ <p><img src="{@docRoot}images/tools/studio-sample-in-editor.png" /></p>
+ <p class="img-caption"><strong>Figure 3.</strong> Imported code sample.</p>
+
+
+
+<h2 id="template-support">Expanded Template and Form Factor Support</h2>
+<p>Android Studio supports templates for Google Services and expands the available device
+types. </p>
+
+ <h4> Android Wear and TV support</h4>
+ <p>For easy cross-platform development, the Project Wizard provides templates for
+ creating your apps for Android Wear and TV. </p>
+ <p><img src="{@docRoot}images/tools/studio-tvwearsupport.png" />
+
+ <p class="img-caption"><strong>Figure 4.</strong> Supported form factors.</p>
+ <p>During app creation, the Project Wizard also displays an API Level dialog to help you choose
+ the best <em>minSdkVersion</em> for your project.</p>
+
+
+ <h4> Google App Engine integration (Google Cloud Platform/Messaging)</h4>
+ <p>Quick cloud integration. Using Google App Engine to connect to the Google cloud
+ and create a cloud end-point is as easy as selecting <em>File > New Module > App Engine Java
+ Servlet Module</em> and specifying the module, package, and client names. </p>
+ <p><img src="{@docRoot}images/tools/studio-cloudmodule.png" /></p>
+ <p class="img-caption"><strong>Figure 5</strong> Google App Engine integration.</p>
+
+
+<h2 id="project-settings">Android Studio and Project Settings</h2>
+<p>Android Studio provides setting dialogs so you can manage the most important Android Studio and
+project settings from the <strong>File &gt; Project Structure</strong> and
+<strong>File &gt; Settings</strong> menus. For example, you can use the
+<strong>File &gt; Project Structure</strong> menu or
+the <code>build.gradle</code> file to update your <code>productFlavor</code> settings.
+Additional settings from the <strong>File &gt; Project Structure</strong> menus include:
+<ul>
+ <li>SDK and JDK location </li>
+ <li>SDK version </li>
+ <li>Gradle and Android Plugin for Gradle versions </li>
+ <li>Build tools version </li>
+ <li>Multidex setting</li>
+ <li><code>buildTypes</code> </li>
+ <li>Dependencies </li>
+</ul>
+</p>
+
+<p>Use the <strong>File &gt; Settings</strong> menu to modify the Android Studio or project
+behavior, such a UI themes, system settings, and version control. </p>
+
+
+
+<h2 id="support-apis">Editor Support for the Latest Android APIs</h2>
+<p>Android Studio supports the
+<a href="{@docRoot}design/material/index.html">Material Design</a></li> themes, widgets, and
+graphics, such as shadow layers and API version rendering (showing the layout across different
+UI versions). Also, the drawable XML tags and attributes, such as <code>&lt;ripple&gt;</code>
+and <code>&lt;animated-selector&gt;</code>, are supported.</p>
+
+
+
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index a5e617d..db19d4f 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -20,6 +20,10 @@
<a href="<?cs var:toroot?>tools/studio/index.html">Android Studio</a>
</div>
<ul>
+ <li><a href="<?cs var:toroot ?>tools/studio/studio-config.html">
+ Configuration</a></li>
+ <li><a href="<?cs var:toroot ?>tools/studio/studio-features.html">
+ Features</a></li>
<li><a href="<?cs var:toroot ?>sdk/installing/studio-tips.html">
Tips and Tricks</a></li>
</ul>
@@ -151,12 +155,7 @@
<div class="nav-section-header"><a href="<?cs var:toroot ?>tools/help/index.html"><span
class="en">Tools Help</span></a></div>
<ul>
- <li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/help/adb.html">adb</a></div>
- <ul>
- <li><a href="<?cs var:toroot ?>tools/help/shell.html">Shell commands</a></li>
- </ul>
- </li>
+ <li><a href="<?cs var:toroot ?>tools/help/adb.html">adb</a></li>
<li><a href="<?cs var:toroot ?>tools/help/android.html">android</a></li>
<li><a href="<?cs var:toroot ?>tools/help/avd-manager.html">AVD Manager</a></li>
<li><a href="<?cs var:toroot ?>tools/help/bmgr.html">bmgr</a>
@@ -173,7 +172,6 @@ class="en">Tools Help</span></a></div>
<li><a href="<?cs var:toroot ?>tools/help/mksdcard.html">mksdcard</a></li>
<li><a href="<?cs var:toroot ?>tools/help/proguard.html" zh-cn-lang="ProGuard">ProGuard</a></li>
<li><a href="<?cs var:toroot ?>tools/help/sdk-manager.html">SDK Manager</a></li>
- <li><a href="<?cs var:toroot ?>tools/help/sqlite3.html">sqlite3</a></li>
<li><a href="<?cs var:toroot ?>tools/help/systrace.html">Systrace</a></li>
<li><a href="<?cs var:toroot ?>tools/help/gltracer.html">Tracer for OpenGL ES</a></li>
<li><a href="<?cs var:toroot ?>tools/help/traceview.html">Traceview</a></li>
@@ -195,11 +193,14 @@ class="en">Tools Help</span></a></div>
<span class="en">Configuring Gradle Builds</span></a></li>
<li><a href="<?cs var:toroot ?>tools/building/plugin-for-gradle.html">
<span class="en">Android Plugin for Gradle</span></a></li>
+ <li><a href="<?cs var:toroot ?>tools/building/manifest-merge.html">
+ <span class="en">Manifest Merging</span></a></li>
<li><a href="<?cs var:toroot ?>tools/building/multidex.html">
<span class="en">Apps Over 65K Methods</span></a></li>
</ul>
</li><!-- end of build system -->
+
<!-- Performance Tools menu-->
<li class="nav-section">
<div class="nav-section-header">
@@ -260,6 +261,7 @@ class="en">Tools Help</span></a></div>
</ul>
</li><!-- End Performance Tools menu-->
+
<!-- Testing Tools menu-->
<li class="nav-section">
@@ -357,7 +359,15 @@ class="en">Data Binding Library</span></a></div>
<span class="en">Eclipse with ADT</span></a>
</div>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/installing/migrate.html">Migrating to Android Studio</a></li>
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>sdk/installing/migrate.html">
+ <span class="en">Migrating to Android Studio</span></a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>tools/studio/eclipse-transition-guide.html">
+ Transition Guide</span></a> </li>
+ </ul>
+ </li>
+
<li><a href="<?cs var:toroot ?>sdk/installing/installing-adt.html">
<span class="en">Installing the Eclipse Plugin</span></a></li>
<li><a href="<?cs var:toroot ?>tools/projects/projects-eclipse.html">Managing Projects</a></li>
diff --git a/docs/html/tools/workflow/index.jd b/docs/html/tools/workflow/index.jd
index a24a2b0..b32fa26 100644
--- a/docs/html/tools/workflow/index.jd
+++ b/docs/html/tools/workflow/index.jd
@@ -41,16 +41,16 @@ figure 1. The development steps encompass four development phases, which include
<a href="{@docRoot}tools/projects/index.html">Create an Android project</a>.</p>
</li>
<li><strong>Building, Debugging and Testing</strong>
- <p>During this phase you build your project into a debuggable <code>.apk</code> package(s)
- that you can install and run on the emulator or an Android-powered device. Android Studio uses
- a build system based on <a href="http://www.gradle.org/" target="_android">Gradle</a>
- that provides flexibility, customized build variants, dependency resolution, and much more.
- If you're using another IDE, you can build your project using Gradle and install it on a device
+ <p>During this phase you build your project into a debuggable <code>.apk</code> package(s)
+ that you can install and run on the emulator or an Android-powered device. Android Studio uses
+ a build system based on <a href="http://www.gradle.org/" target="_android">Gradle</a>
+ that provides flexibility, customized build variants, dependency resolution, and much more.
+ If you're using another IDE, you can build your project using Gradle and install it on a device
using <a href="{@docRoot}tools/help/adb.html">adb</a>. For more information, see
<a href="{@docRoot}tools/building/index.html">Build and run your application</a>.</p>
<p>Next, with Android Studio you debug your application using the
- <a href="{@docRoot}tools/help/monitor.html">Android Debug Monitor</a> and device log messages
- (<a href="{@docRoot}tools/help/logcat.html">logact</a>) along with the IntelliJ IDEA intelligent
+ <a href="{@docRoot}tools/help/monitor.html">Android Device Monitor</a> and device log messages
+ (<a href="{@docRoot}tools/help/logcat.html">logcat</a>) along with the IntelliJ IDEA intelligent
coding features. You can also use a JDWP-compliant debugger along with the debugging and logging
tools that are provided with the Android SDK. For more information see
<a href="{@docRoot}tools/debugging/index.html">Debug your application with the SDK debugging and logging tools</a>.</p>
diff --git a/docs/html/training/material/drawables.jd b/docs/html/training/material/drawables.jd
index a2de8e9..c58075e 100644
--- a/docs/html/training/material/drawables.jd
+++ b/docs/html/training/material/drawables.jd
@@ -36,8 +36,9 @@ alpha masks. You can tint them with color resources or theme attributes that res
resources (for example, <code>?android:attr/colorPrimary</code>). Usually, you create these assets
only once and color them automatically to match your theme.</p>
-<p>You can apply a tint to {@link android.graphics.drawable.BitmapDrawable} or {@link
-android.graphics.drawable.NinePatchDrawable} objects with the {@code setTint()} method. You can
+<p>You can apply a tint to {@link android.graphics.drawable.BitmapDrawable}, {@link
+android.graphics.drawable.NinePatchDrawable} or {@link
+android.graphics.drawable.VectorDrawable} objects with the {@code setTint()} method. You can
also set the tint color and mode in your layouts with the <code>android:tint</code> and
<code>android:tintMode</code> attributes.</p>
diff --git a/docs/html/training/safetynet/index.jd b/docs/html/training/safetynet/index.jd
index 6090f41..6d822c6 100644
--- a/docs/html/training/safetynet/index.jd
+++ b/docs/html/training/safetynet/index.jd
@@ -325,7 +325,7 @@ certificate used to sign requesting app"],
<li>Obtain your API key by expanding <strong>APIs &amp; auth</strong> and
clicking <strong>Credentials</strong>.
- Record the <strong>API KEY</strong> value on this page for later use.
+ Record the <strong>API KEY</strong> (<em>not</em> the <em>Android Key</em>) value on this page for later use.
</li>
</ol>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index e1e6838..5279969 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -91,25 +91,60 @@ include the action bar on devices running Android 2.1 or higher."
<li class="nav-section">
<div class="nav-section-header">
<a href="<?cs var:toroot ?>training/basics/activity-lifecycle/index.html"
+ es-lang=""
+ ja-lang="アクティビティのライフサイクル 管理"
+ ko-lang="액티비티 수명 주기 관리하기"
+ pt-br-lang="Como gerenciar o ciclo de vida da atividade"
+ ru-lang="Управление жизненным циклом операций"
+ zh-cn-lang="管理活动生命周期"
+ zh-tw-lang="管理應用行為顯示生命週期"
description=
"How Android activities live and die and how to create
a seamless user experience by implementing lifecycle callback methods."
>Managing the Activity Lifecycle</a>
</div>
<ul>
- <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/starting.html">
+ <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/starting.html"
+ es-lang=""
+ ja-lang="アクティビティを開始する"
+ ko-lang="액티비티 시작하기"
+ pt-br-lang="Iniciando uma atividade"
+ ru-lang="Запуск операции"
+ zh-cn-lang="开始活动"
+ zh-tw-lang="啟動應用行為顯示">
Starting an Activity
</a>
</li>
- <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/pausing.html">
+ <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/pausing.html"
+ es-lang=""
+ ja-lang=""
+ ko-lang=""
+ pt-br-lang=""
+ ru-lang=""
+ zh-cn-lang=""
+ zh-tw-lang="">
Pausing and Resuming an Activity
</a>
</li>
- <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/stopping.html">
+ <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/stopping.html"
+ es-lang=""
+ ja-lang="アクティビティの一時停止と再開"
+ ko-lang="액티비티 일시정지 및 재개하기"
+ pt-br-lang="Pausando e reiniciando uma atividade"
+ ru-lang="Приостановка и возобновление операции"
+ zh-cn-lang="暂停和继续活动"
+ zh-tw-lang="暫停並繼續應用行為顯示">
Stopping and Restarting an Activity
</a>
</li>
- <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/recreating.html">
+ <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/recreating.html"
+ es-lang=""
+ ja-lang="アクティビティを再作成する"
+ ko-lang="액티비티 재생성하기"
+ pt-br-lang="Recriando uma atividade"
+ ru-lang="Воссоздание операции"
+ zh-cn-lang="重新创建活动"
+ zh-tw-lang="重新建立應用行為顯示">
Recreating an Activity
</a>
</li>
@@ -144,21 +179,49 @@ include the action bar on devices running Android 2.1 or higher."
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot?>training/basics/data-storage/index.html"
+ es-lang=""
+ ja-lang="データの保存"
+ ko-lang="데이터 저장하기"
+ pt-br-lang="Salvando dados"
+ ru-lang="Сохранение данных"
+ zh-cn-lang="保存数据"
+ zh-tw-lang="儲存資料"
description=
"How to save data on the device, whether it's temporary files, downloaded
app assets, user media, structured data, or something else."
>Saving Data</a>
</div>
<ul>
- <li><a href="<?cs var:toroot ?>training/basics/data-storage/shared-preferences.html">
+ <li><a href="<?cs var:toroot ?>training/basics/data-storage/shared-preferences.html"
+ es-lang=""
+ ja-lang="キー値セットを保存する"
+ ko-lang="키-값 세트 저장하기"
+ pt-br-lang="Salvando conjuntos de valor-chave"
+ ru-lang="Сохранение наборов "\"ключ-значение\""
+ zh-cn-lang="保存键值集"
+ zh-tw-lang="儲存索引鍵值組">
Saving Key-Value Sets
</a>
</li>
- <li><a href="<?cs var:toroot ?>training/basics/data-storage/files.html">
+ <li><a href="<?cs var:toroot ?>training/basics/data-storage/files.html"
+ es-lang=""
+ ja-lang="ファイルを保存する"
+ ko-lang="파일 저장하기"
+ pt-br-lang="Salvando arquivos"
+ ru-lang="Сохранение файлов"
+ zh-cn-lang="保存文件"
+ zh-tw-lang="儲存檔案">
Saving Files
</a>
</li>
- <li><a href="<?cs var:toroot ?>training/basics/data-storage/databases.html">
+ <li><a href="<?cs var:toroot ?>training/basics/data-storage/databases.html"
+ es-lang=""
+ ja-lang="SQL データベースにデータを保存する"
+ ko-lang="SQL 데이터베이스에 데이터 저장하기"
+ pt-br-lang="Salvando dados em bancos de dados do SQL"
+ ru-lang="Сохранение данных в базах данных SQL"
+ zh-cn-lang="在 SQL 数据库中保存数据"
+ zh-tw-lang="在 SQL 資料庫中儲存資料">
Saving Data in SQL Databases
</a>
</li>
@@ -168,6 +231,13 @@ include the action bar on devices running Android 2.1 or higher."
<li class="nav-section">
<div class="nav-section-header">
<a href="<?cs var:toroot ?>training/basics/intents/index.html"
+ es-lang=""
+ ja-lang="他のアプリとの相互操作"
+ ko-lang="액티비티 수명 주기 관리하기"
+ pt-br-lang="Interagindo com outros aplicativos"
+ ru-lang="Взаимодействие с другими приложениями"
+ zh-cn-lang="与其他应用交互"
+ zh-tw-lang="與其他應用程式互動"
description=
"How to build a user experience that leverages other apps available
on the device to perform advanced user tasks, such as capture a photo or view
@@ -175,15 +245,36 @@ include the action bar on devices running Android 2.1 or higher."
>Interacting with Other Apps</a>
</div>
<ul>
- <li><a href="<?cs var:toroot ?>training/basics/intents/sending.html">
+ <li><a href="<?cs var:toroot ?>training/basics/intents/sending.html"
+ es-lang=""
+ ja-lang="別のアプリにユーザーを送る"
+ ko-lang="다른 앱으로 사용자 보내기"
+ pt-br-lang="Enviando o usuário para outro aplicativo"
+ ru-lang="Направление пользователя в другое приложение"
+ zh-cn-lang="向另一个应用发送用户"
+ zh-tw-lang="將使用者傳送至其他應用程式">
Sending the User to Another App
</a>
</li>
- <li><a href="<?cs var:toroot ?>training/basics/intents/result.html">
+ <li><a href="<?cs var:toroot ?>training/basics/intents/result.html"
+ es-lang=""
+ ja-lang="アクティビティから結果を取得する"
+ ko-lang="액티비티로부터 결과 가져오기"
+ pt-br-lang="Obtendo resultados de uma atividade"
+ ru-lang="Получение результата операции"
+ zh-cn-lang="获取活动的结果"
+ zh-tw-lang="從應用行為顯示取得結果">
Getting a Result from the Activity
</a>
</li>
- <li><a href="<?cs var:toroot ?>training/basics/intents/filters.html">
+ <li><a href="<?cs var:toroot ?>training/basics/intents/filters.html"
+ es-lang=""
+ ja-lang="他のアプリからのアクティビティの開始を許可する"
+ ko-lang="다른 앱이 자신의 액티비티를 시작하도록 허용하기"
+ pt-br-lang="Permitindo que outros aplicativos iniciem sua atividade"
+ ru-lang="Разрешение другим приложениям на запуск вашей операции"
+ zh-cn-lang="允许其他应用开始您的活动"
+ zh-tw-lang="允許其他應用程式啟動您的應用行為顯示">
Allowing Other Apps to Start Your Activity
</a>
</li>
diff --git a/docs/html/training/volley/requestqueue.jd b/docs/html/training/volley/requestqueue.jd
index 5e892bf..6d19cee 100644
--- a/docs/html/training/volley/requestqueue.jd
+++ b/docs/html/training/volley/requestqueue.jd
@@ -139,7 +139,8 @@ rotates the device).
<p>Here is an example of a singleton class that provides {@code RequestQueue} and
{@code ImageLoader} functionality:</p>
-<pre>private static MySingleton mInstance;
+<pre>public class MySingleton {
+ private static MySingleton mInstance;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static Context mCtx;
diff --git a/docs/html/training/wearables/watch-faces/drawing.jd b/docs/html/training/wearables/watch-faces/drawing.jd
index 8b6de76..30a7a6f 100644
--- a/docs/html/training/wearables/watch-faces/drawing.jd
+++ b/docs/html/training/wearables/watch-faces/drawing.jd
@@ -457,9 +457,23 @@ watch face. The bounds take into account any inset areas, such as the "chin" on
round devices. You can use this canvas to draw your watch face directly as follows:</p>
<ol>
-<li>If this is the first invocation of the
-<a href="{@docRoot}reference/android/support/wearable/watchface/CanvasWatchFaceService.Engine.html#onDraw(android.graphics.Canvas, android.graphics.Rect)"><code>onDraw()</code></a>
-method, scale your background to fit.</li>
+<li>Override the
+<a href="{@docRoot}reference/android/support/wearable/watchface/CanvasWatchFaceService.Engine.html#onSurfaceChanged(android.view.SurfaceHolder, int, int, int)"><code>onSurfaceChanged()</code></a>
+method to scale your background to fit the device any time the view changes.
+<pre>
+&#64;Override
+public void onSurfaceChanged(
+ SurfaceHolder holder, int format, int width, int height) {
+ if (mBackgroundScaledBitmap == null
+ || mBackgroundScaledBitmap.getWidth() != width
+ || mBackgroundScaledBitmap.getHeight() != height) {
+ mBackgroundScaledBitmap = Bitmap.createScaledBitmap(mBackgroundBitmap,
+ width, height, true /* filter */);
+ }
+ super.onSurfaceChanged(holder, format, width, height);
+}
+</pre>
+</li>
<li>Check whether the device is in ambient mode or interactive mode.</li>
<li>Perform any required graphic computations.</li>
<li>Draw your background bitmap on the canvas.</li>
@@ -482,13 +496,6 @@ public void onDraw(Canvas canvas, Rect bounds) {
int width = bounds.width();
int height = bounds.height();
- // Draw the background, scaled to fit.
- if (mBackgroundScaledBitmap == null
- || mBackgroundScaledBitmap.getWidth() != width
- || mBackgroundScaledBitmap.getHeight() != height) {
- mBackgroundScaledBitmap = Bitmap.createScaledBitmap(mBackgroundBitmap,
- width, height, true);
- }
canvas.drawBitmap(mBackgroundScaledBitmap, 0, 0, null);
// Find the center. Ignore the window insets so that, on round watches
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index 3058bd3..459514d 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -287,6 +287,22 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
mKeymasterBlockModes = KeyProperties.BlockMode.allToKeymaster(spec.getBlockModes());
mKeymasterEncryptionPaddings = KeyProperties.EncryptionPadding.allToKeymaster(
spec.getEncryptionPaddings());
+ if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0)
+ && (spec.isRandomizedEncryptionRequired())) {
+ for (int keymasterPadding : mKeymasterEncryptionPaddings) {
+ if (!KeymasterUtils
+ .isKeymasterPaddingSchemeIndCpaCompatibleWithAsymmetricCrypto(
+ keymasterPadding)) {
+ throw new InvalidAlgorithmParameterException(
+ "Randomized encryption (IND-CPA) required but may be violated"
+ + " by padding scheme: "
+ + KeyProperties.EncryptionPadding.fromKeymaster(
+ keymasterPadding)
+ + ". See " + KeyGenParameterSpec.class.getName()
+ + " documentation.");
+ }
+ }
+ }
mKeymasterSignaturePaddings = KeyProperties.SignaturePadding.allToKeymaster(
spec.getSignaturePaddings());
if (spec.isDigestsSpecified()) {
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
index de483f4..dc8f1e3 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -140,21 +140,64 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
throw new NullPointerException("alias == null");
}
- byte[] certificate = mKeyStore.get(Credentials.USER_CERTIFICATE + alias);
- if (certificate != null) {
- return wrapIntoKeyStoreCertificate(
- Credentials.USER_PRIVATE_KEY + alias, toCertificate(certificate));
+ byte[] encodedCert = mKeyStore.get(Credentials.USER_CERTIFICATE + alias);
+ if (encodedCert != null) {
+ return getCertificateForPrivateKeyEntry(alias, encodedCert);
}
- certificate = mKeyStore.get(Credentials.CA_CERTIFICATE + alias);
- if (certificate != null) {
- return wrapIntoKeyStoreCertificate(
- Credentials.USER_PRIVATE_KEY + alias, toCertificate(certificate));
+ encodedCert = mKeyStore.get(Credentials.CA_CERTIFICATE + alias);
+ if (encodedCert != null) {
+ return getCertificateForTrustedCertificateEntry(encodedCert);
}
+ // This entry/alias does not contain a certificate.
return null;
}
+ private Certificate getCertificateForTrustedCertificateEntry(byte[] encodedCert) {
+ // For this certificate there shouldn't be a private key in this KeyStore entry. Thus,
+ // there's no need to wrap this certificate as opposed to the certificate associated with
+ // a private key entry.
+ return toCertificate(encodedCert);
+ }
+
+ private Certificate getCertificateForPrivateKeyEntry(String alias, byte[] encodedCert) {
+ // All crypto algorithms offered by Android Keystore for its private keys must also
+ // be offered for the corresponding public keys stored in the Android Keystore. The
+ // complication is that the underlying keystore service operates only on full key pairs,
+ // rather than just public keys or private keys. As a result, Android Keystore-backed
+ // crypto can only be offered for public keys for which keystore contains the
+ // corresponding private key. This is not the case for certificate-only entries (e.g.,
+ // trusted certificates).
+ //
+ // getCertificate().getPublicKey() is the only way to obtain the public key
+ // corresponding to the private key stored in the KeyStore. Thus, we need to make sure
+ // that the returned public key points to the underlying key pair / private key
+ // when available.
+
+ X509Certificate cert = toCertificate(encodedCert);
+ if (cert == null) {
+ // Failed to parse the certificate.
+ return null;
+ }
+
+ String privateKeyAlias = Credentials.USER_PRIVATE_KEY + alias;
+ if (mKeyStore.contains(privateKeyAlias)) {
+ // As expected, keystore contains the private key corresponding to this public key. Wrap
+ // the certificate so that its getPublicKey method returns an Android Keystore
+ // PublicKey. This key will delegate crypto operations involving this public key to
+ // Android Keystore when higher-priority providers do not offer these crypto
+ // operations for this key.
+ return wrapIntoKeyStoreCertificate(privateKeyAlias, cert);
+ } else {
+ // This KeyStore entry/alias is supposed to contain the private key corresponding to
+ // the public key in this certificate, but it does not for some reason. It's probably a
+ // bug. Let other providers handle crypto operations involving the public key returned
+ // by this certificate's getPublicKey.
+ return cert;
+ }
+ }
+
/**
* Wraps the provided cerificate into {@link KeyStoreX509Certificate} so that the public key
* returned by the certificate contains information about the alias of the private key in
diff --git a/keystore/java/android/security/keystore/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java
index 0006601..3cd3f2a 100644
--- a/keystore/java/android/security/keystore/KeymasterUtils.java
+++ b/keystore/java/android/security/keystore/KeymasterUtils.java
@@ -74,7 +74,7 @@ public abstract class KeymasterUtils {
return true;
default:
throw new IllegalArgumentException(
- "Unsupported encryption padding scheme: " + keymasterPadding);
+ "Unsupported asymmetric encryption padding scheme: " + keymasterPadding);
}
}
diff --git a/libs/hwui/Android.common.mk b/libs/hwui/Android.common.mk
index 9590595..38e8be9 100644
--- a/libs/hwui/Android.common.mk
+++ b/libs/hwui/Android.common.mk
@@ -119,6 +119,7 @@ endif
# Defaults for ATRACE_TAG and LOG_TAG for libhwui
LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_VIEW -DLOG_TAG=\"OpenGLRenderer\"
LOCAL_CFLAGS += -Wall -Wno-unused-parameter -Wunreachable-code
+LOCAL_CFLAGS += -ffast-math -O3
# b/21698669
ifneq ($(USE_CLANG_PLATFORM_BUILD),true)
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index fb2852a..d2bf138 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -29,6 +29,8 @@
#include "utils/LinearAllocator.h"
#include "utils/PaintUtils.h"
+#include <algorithm>
+
#include <SkColor.h>
#include <SkPath.h>
#include <SkPathOps.h>
@@ -184,7 +186,7 @@ public:
// TODO: it would be nice if this could take scale into account, but scale isn't stable
// since higher levels of the view hierarchy can change scale out from underneath it.
- return fmaxf(mPaint->getStrokeWidth(), 1) * 0.5f;
+ return std::max(mPaint->getStrokeWidth(), 1.0f) * 0.5f;
}
protected:
@@ -235,10 +237,10 @@ public:
DrawBoundedOp(const float* points, int count, const SkPaint* paint)
: DrawOp(paint), mLocalBounds(points[0], points[1], points[0], points[1]) {
for (int i = 2; i < count; i += 2) {
- mLocalBounds.left = fminf(mLocalBounds.left, points[i]);
- mLocalBounds.right = fmaxf(mLocalBounds.right, points[i]);
- mLocalBounds.top = fminf(mLocalBounds.top, points[i + 1]);
- mLocalBounds.bottom = fmaxf(mLocalBounds.bottom, points[i + 1]);
+ mLocalBounds.left = std::min(mLocalBounds.left, points[i]);
+ mLocalBounds.right = std::max(mLocalBounds.right, points[i]);
+ mLocalBounds.top = std::min(mLocalBounds.top, points[i + 1]);
+ mLocalBounds.bottom = std::max(mLocalBounds.bottom, points[i + 1]);
}
}
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 3d48fa6..87ed84f 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1626,10 +1626,10 @@ void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int m
ColorTextureVertex::set(vertex++, vertices[bx], vertices[by], u1, v1, colors[bx / 2]);
ColorTextureVertex::set(vertex++, vertices[cx], vertices[cy], u2, v1, colors[cx / 2]);
- left = fminf(left, fminf(vertices[ax], fminf(vertices[bx], vertices[cx])));
- top = fminf(top, fminf(vertices[ay], fminf(vertices[by], vertices[cy])));
- right = fmaxf(right, fmaxf(vertices[ax], fmaxf(vertices[bx], vertices[cx])));
- bottom = fmaxf(bottom, fmaxf(vertices[ay], fmaxf(vertices[by], vertices[cy])));
+ left = std::min(left, std::min(vertices[ax], std::min(vertices[bx], vertices[cx])));
+ top = std::min(top, std::min(vertices[ay], std::min(vertices[by], vertices[cy])));
+ right = std::max(right, std::max(vertices[ax], std::max(vertices[bx], vertices[cx])));
+ bottom = std::max(bottom, std::max(vertices[ay], std::max(vertices[by], vertices[cy])));
}
}
@@ -2127,8 +2127,8 @@ bool OpenGLRenderer::findBestFontTransform(const mat4& transform, SkMatrix* outM
float sx, sy;
transform.decomposeScale(sx, sy);
outMatrix->setScale(
- roundf(fmaxf(1.0f, sx)),
- roundf(fmaxf(1.0f, sy)));
+ roundf(std::max(1.0f, sx)),
+ roundf(std::max(1.0f, sy)));
return true;
}
@@ -2551,10 +2551,10 @@ void OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint
Vertex::set(vertex++, l, b);
Vertex::set(vertex++, r, b);
- left = fminf(left, l);
- top = fminf(top, t);
- right = fmaxf(right, r);
- bottom = fmaxf(bottom, b);
+ left = std::min(left, l);
+ top = std::min(top, t);
+ right = std::max(right, r);
+ bottom = std::max(bottom, b);
}
if (clip && quickRejectSetupScissor(left, top, right, bottom)) {
diff --git a/libs/hwui/Outline.h b/libs/hwui/Outline.h
index 5e9b213..c98932c 100644
--- a/libs/hwui/Outline.h
+++ b/libs/hwui/Outline.h
@@ -19,6 +19,7 @@
#include <SkPath.h>
#include "Rect.h"
+#include "utils/MathUtils.h"
namespace android {
namespace uirenderer {
@@ -85,6 +86,11 @@ public:
return mShouldClip && (mType == kOutlineType_RoundRect);
}
+ bool willRoundRectClip() const {
+ // only round rect outlines can be used for clipping
+ return willClip() && MathUtils::isPositive(mRadius);
+ }
+
bool getAsRoundRect(Rect* outRect, float* outRadius) const {
if (mType == kOutlineType_RoundRect) {
outRect->set(mBounds);
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index f673c6a..f4dd943 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -81,9 +81,9 @@ Patch::Patch(const float bitmapWidth, const float bitmapHeight,
}
const float xStretchTex = stretchSize;
const float fixed = bitmapWidth - stretchSize;
- const float xStretch = fmaxf(width - fixed, 0.0f);
+ const float xStretch = std::max(width - fixed, 0.0f);
stretchX = xStretch / xStretchTex;
- rescaleX = fixed == 0.0f ? 0.0f : fminf(fmaxf(width, 0.0f) / fixed, 1.0f);
+ rescaleX = fixed == 0.0f ? 0.0f : std::min(std::max(width, 0.0f) / fixed, 1.0f);
}
if (yStretchCount > 0) {
@@ -93,9 +93,9 @@ Patch::Patch(const float bitmapWidth, const float bitmapHeight,
}
const float yStretchTex = stretchSize;
const float fixed = bitmapHeight - stretchSize;
- const float yStretch = fmaxf(height - fixed, 0.0f);
+ const float yStretch = std::max(height - fixed, 0.0f);
stretchY = yStretch / yStretchTex;
- rescaleY = fixed == 0.0f ? 0.0f : fminf(fmaxf(height, 0.0f) / fixed, 1.0f);
+ rescaleY = fixed == 0.0f ? 0.0f : std::min(std::max(height, 0.0f) / fixed, 1.0f);
}
uint32_t quadCount = 0;
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index c82082f..4c4cd3d 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -18,6 +18,7 @@
#define ANDROID_HWUI_RECT_H
#include <cmath>
+#include <algorithm>
#include <SkRect.h>
#include <utils/Log.h>
@@ -246,17 +247,17 @@ public:
}
void expandToCoverVertex(float x, float y) {
- left = fminf(left, x);
- top = fminf(top, y);
- right = fmaxf(right, x);
- bottom = fmaxf(bottom, y);
+ left = std::min(left, x);
+ top = std::min(top, y);
+ right = std::max(right, x);
+ bottom = std::max(bottom, y);
}
void expandToCoverRect(float otherLeft, float otherTop, float otherRight, float otherBottom) {
- left = fminf(left, otherLeft);
- top = fminf(top, otherTop);
- right = fmaxf(right, otherRight);
- bottom = fmaxf(bottom, otherBottom);
+ left = std::min(left, otherLeft);
+ top = std::min(top, otherTop);
+ right = std::max(right, otherRight);
+ bottom = std::max(bottom, otherBottom);
}
SkRect toSkRect() const {
@@ -273,18 +274,18 @@ public:
private:
void intersectWith(Rect& tmp) const {
- tmp.left = fmaxf(left, tmp.left);
- tmp.top = fmaxf(top, tmp.top);
- tmp.right = fminf(right, tmp.right);
- tmp.bottom = fminf(bottom, tmp.bottom);
+ tmp.left = std::max(left, tmp.left);
+ tmp.top = std::max(top, tmp.top);
+ tmp.right = std::min(right, tmp.right);
+ tmp.bottom = std::min(bottom, tmp.bottom);
}
Rect intersectWith(float l, float t, float r, float b) const {
Rect tmp;
- tmp.left = fmaxf(left, l);
- tmp.top = fmaxf(top, t);
- tmp.right = fminf(right, r);
- tmp.bottom = fminf(bottom, b);
+ tmp.left = std::max(left, l);
+ tmp.top = std::max(top, t);
+ tmp.right = std::min(right, r);
+ tmp.bottom = std::min(bottom, b);
return tmp;
}
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index 81cf2df..11abd70 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -169,7 +169,7 @@ public:
bool functorsNeedLayer = ancestorDictatesFunctorsNeedLayer
// Round rect clipping forces layer for functors
- || CC_UNLIKELY(getOutline().willClip())
+ || CC_UNLIKELY(getOutline().willRoundRectClip())
|| CC_UNLIKELY(getRevealClip().willClip())
// Complex matrices forces layer, due to stencil clipping
diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp
index 024ff10..09d1258 100644
--- a/libs/hwui/ShadowTessellator.cpp
+++ b/libs/hwui/ShadowTessellator.cpp
@@ -21,6 +21,7 @@
#include <utils/Log.h>
#include <utils/Trace.h>
#include <utils/Vector.h>
+#include <utils/MathUtils.h>
#include "AmbientShadow.h"
#include "Properties.h"
@@ -172,6 +173,8 @@ int ShadowTessellator::getExtraVertexNumber(const Vector2& vector1,
// acos( ) --- [0, M_PI]
// floor(...) --- [0, EXTRA_VERTEX_PER_PI]
float dotProduct = vector1.dot(vector2);
+ // make sure that dotProduct value is in acsof input range [-1, 1]
+ dotProduct = MathUtils::clamp(dotProduct, -1.0f, 1.0f);
// TODO: Use look up table for the dotProduct to extraVerticesNumber
// computation, if needed.
float angle = acosf(dotProduct);
diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp
index db3c2d9..b8c9804 100644
--- a/libs/hwui/SpotShadow.cpp
+++ b/libs/hwui/SpotShadow.cpp
@@ -48,6 +48,7 @@
#define TRANSFORMED_PENUMBRA_ALPHA 1.0f
#define TRANSFORMED_UMBRA_ALPHA 0.0f
+#include <algorithm>
#include <math.h>
#include <stdlib.h>
#include <utils/Log.h>
@@ -145,7 +146,10 @@ static float rayIntersectPoints(const Vector2& rayOrigin, float dx, float dy,
* @param pointsLength the number of vertices of the polygon.
*/
void SpotShadow::xsort(Vector2* points, int pointsLength) {
- quicksortX(points, 0, pointsLength - 1);
+ auto cmp = [](const Vector2& a, const Vector2& b) -> bool {
+ return a.x < b.x;
+ };
+ std::sort(points, points + pointsLength, cmp);
}
/**
@@ -273,35 +277,6 @@ void SpotShadow::quicksortCirc(Vector2* points, int low, int high,
}
/**
- * Sort points by x axis
- *
- * @param points points to sort
- * @param low start index
- * @param high end index
- */
-void SpotShadow::quicksortX(Vector2* points, int low, int high) {
- int i = low, j = high;
- int p = low + (high - low) / 2;
- float pivot = points[p].x;
- while (i <= j) {
- while (points[i].x < pivot) {
- i++;
- }
- while (points[j].x > pivot) {
- j--;
- }
-
- if (i <= j) {
- swap(points, i, j);
- i++;
- j--;
- }
- }
- if (low < j) quicksortX(points, low, j);
- if (i < high) quicksortX(points, i, high);
-}
-
-/**
* Test whether a point is inside the polygon.
*
* @param testPoint the point to test
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 5147e98..fe1b7fd 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -93,7 +93,7 @@ void TextureCache::setMaxSize(uint32_t maxSize) {
}
void TextureCache::setFlushRate(float flushRate) {
- mFlushRate = fmaxf(0.0f, fminf(1.0f, flushRate));
+ mFlushRate = std::max(0.0f, std::min(1.0f, flushRate));
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index b07a3c8..5de64a4 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -228,15 +228,15 @@ void Font::drawCachedGlyphBitmap(CachedGlyphInfo* glyph, int x, int y, uint8_t*
for (uint32_t cacheY = startY, bitmapY = dstY * bitmapWidth; cacheY < endY;
cacheY += srcStride, bitmapY += bitmapWidth) {
- if (formatSize == 1) {
- memcpy(&bitmap[bitmapY + dstX], &cacheBuffer[cacheY + glyph->mStartX], glyph->mBitmapWidth);
- } else {
- for (uint32_t i = 0; i < glyph->mBitmapWidth; ++i) {
- bitmap[bitmapY + dstX + i] = cacheBuffer[cacheY + (glyph->mStartX + i)*formatSize + alpha_channel_offset];
- }
+ for (uint32_t i = 0; i < glyph->mBitmapWidth; ++i) {
+ uint8_t* dst = &(bitmap[bitmapY + dstX + i]);
+ const uint8_t& src = cacheBuffer[
+ cacheY + (glyph->mStartX + i)*formatSize + alpha_channel_offset];
+ // Add alpha values to a max of 255, full opacity. This is done to handle
+ // fonts/strings where glyphs overlap.
+ *dst = std::min(*dst + src, 255);
}
}
-
}
void Font::drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float vOffset,
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index a806440..2c28d8e 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -204,6 +204,17 @@ public class AudioManager {
public static final String EXTRA_VOLUME_STREAM_TYPE = "android.media.EXTRA_VOLUME_STREAM_TYPE";
/**
+ * @hide
+ * The stream type alias for the volume changed intent.
+ * For instance the intent may indicate a change of the {@link #STREAM_NOTIFICATION} stream
+ * type (as indicated by the {@link #EXTRA_VOLUME_STREAM_TYPE} extra), but this is also
+ * reflected by a change of the volume of its alias, {@link #STREAM_RING} on some devices,
+ * {@link #STREAM_MUSIC} on others (e.g. a television).
+ */
+ public static final String EXTRA_VOLUME_STREAM_TYPE_ALIAS =
+ "android.media.EXTRA_VOLUME_STREAM_TYPE_ALIAS";
+
+ /**
* @hide The volume associated with the stream for the volume changed intent.
*/
public static final String EXTRA_VOLUME_STREAM_VALUE =
@@ -619,10 +630,6 @@ public class AudioManager {
com.android.internal.R.bool.config_useVolumeKeySounds);
mUseFixedVolume = getContext().getResources().getBoolean(
com.android.internal.R.bool.config_useFixedVolume);
- sAudioPortEventHandler.init();
-
- mPortListener = new OnAmPortUpdateListener();
- registerAudioPortUpdateListener(mPortListener);
}
private Context getContext() {
@@ -3554,6 +3561,7 @@ public class AudioManager {
* @hide
*/
public void registerAudioPortUpdateListener(OnAudioPortUpdateListener l) {
+ sAudioPortEventHandler.init();
sAudioPortEventHandler.registerListener(l);
}
@@ -3586,6 +3594,7 @@ public class AudioManager {
static int updateAudioPortCache(ArrayList<AudioPort> ports, ArrayList<AudioPatch> patches,
ArrayList<AudioPort> previousPorts) {
+ sAudioPortEventHandler.init();
synchronized (sAudioPortGeneration) {
if (sAudioPortGeneration == AUDIOPORT_GENERATION_INIT) {
@@ -3849,6 +3858,12 @@ public class AudioManager {
android.os.Handler handler) {
if (callback != null && !mDeviceCallbacks.containsKey(callback)) {
synchronized (mDeviceCallbacks) {
+ if (mDeviceCallbacks.size() == 0) {
+ if (mPortListener == null) {
+ mPortListener = new OnAmPortUpdateListener();
+ }
+ registerAudioPortUpdateListener(mPortListener);
+ }
NativeEventHandlerDelegate delegate =
new NativeEventHandlerDelegate(callback, handler);
mDeviceCallbacks.put(callback, delegate);
@@ -3867,6 +3882,9 @@ public class AudioManager {
synchronized (mDeviceCallbacks) {
if (mDeviceCallbacks.containsKey(callback)) {
mDeviceCallbacks.remove(callback);
+ if (mDeviceCallbacks.size() == 0) {
+ unregisterAudioPortUpdateListener(mPortListener);
+ }
}
}
}
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 6c26220..f42fab7 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -701,10 +701,10 @@ public final class MediaCodecInfo {
final Map<String, Object> global = MediaCodecList.getGlobalSettings();
mMaxSupportedInstances = Utils.parseIntSafely(
- global.get("max-supported-instances"), DEFAULT_MAX_SUPPORTED_INSTANCES);
+ global.get("max-concurrent-instances"), DEFAULT_MAX_SUPPORTED_INSTANCES);
int maxInstances = Utils.parseIntSafely(
- map.get("max-supported-instances"), mMaxSupportedInstances);
+ map.get("max-concurrent-instances"), mMaxSupportedInstances);
mMaxSupportedInstances =
Range.create(1, MAX_SUPPORTED_INSTANCES_LIMIT).clamp(maxInstances);
diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml
index 540a38b..0608d27 100644
--- a/packages/DocumentsUI/res/values-af/strings.xml
+++ b/packages/DocumentsUI/res/values-af/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumente"</string>
- <string name="title_open" msgid="4353228937663917801">"Maak oop vanaf"</string>
+ <string name="title_open" msgid="4353228937663917801">"Maak oop vanuit"</string>
<string name="title_save" msgid="2433679664882857999">"Stoor na"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Skep vouer"</string>
<string name="menu_grid" msgid="6878021334497835259">"Roosteraansig"</string>
diff --git a/packages/DocumentsUI/res/values-bn-rBD/strings.xml b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
index a999300..4167194 100644
--- a/packages/DocumentsUI/res/values-bn-rBD/strings.xml
+++ b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
@@ -22,7 +22,7 @@
<string name="menu_create_dir" msgid="5947289605844398389">"ফোল্ডার তৈরি করুন"</string>
<string name="menu_grid" msgid="6878021334497835259">"গ্রিড দৃশ্য"</string>
<string name="menu_list" msgid="7279285939892417279">"তালিকা দৃশ্য"</string>
- <string name="menu_sort" msgid="7677740407158414452">"এর দ্বারা সাজান"</string>
+ <string name="menu_sort" msgid="7677740407158414452">"এই অনুসারে বাছুন"</string>
<string name="menu_search" msgid="3816712084502856974">"অনুসন্ধান করুন"</string>
<string name="menu_settings" msgid="6008033148948428823">"সেটিংস"</string>
<string name="menu_open" msgid="432922957274920903">"খুলুন"</string>
diff --git a/packages/DocumentsUI/res/values-fr-rCA/strings.xml b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
index 14f82ce..03f09ff 100644
--- a/packages/DocumentsUI/res/values-fr-rCA/strings.xml
+++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documents"</string>
- <string name="title_open" msgid="4353228937663917801">"Ouvert à partir de"</string>
+ <string name="title_open" msgid="4353228937663917801">"Ouvrir à partir de"</string>
<string name="title_save" msgid="2433679664882857999">"Enregistrer dans"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Créer un dossier"</string>
<string name="menu_grid" msgid="6878021334497835259">"Grille"</string>
diff --git a/packages/DocumentsUI/res/values-pl/strings.xml b/packages/DocumentsUI/res/values-pl/strings.xml
index 2b79f8e..84e5495 100644
--- a/packages/DocumentsUI/res/values-pl/strings.xml
+++ b/packages/DocumentsUI/res/values-pl/strings.xml
@@ -56,7 +56,7 @@
<string name="empty" msgid="7858882803708117596">"Brak elementów"</string>
<string name="toast_no_application" msgid="1339885974067891667">"Nie można otworzyć pliku"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Nie można usunąć niektórych dokumentów"</string>
- <string name="share_via" msgid="8966594246261344259">"Udostępnij przez"</string>
+ <string name="share_via" msgid="8966594246261344259">"Udostępnij przez:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopiowanie plików"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Pozostało: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
diff --git a/packages/DocumentsUI/res/values-ta-rIN/strings.xml b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
index ca43a7e..bc822fb 100644
--- a/packages/DocumentsUI/res/values-ta-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
@@ -53,7 +53,7 @@
<string name="root_type_shortcut" msgid="3318760609471618093">"குறுக்குவழிகள்"</string>
<string name="root_type_device" msgid="7121342474653483538">"சாதனங்கள்"</string>
<string name="root_type_apps" msgid="8838065367985945189">"மேலும் பயன்பாடுகள்"</string>
- <string name="empty" msgid="7858882803708117596">"உருப்படிகள் இல்லை"</string>
+ <string name="empty" msgid="7858882803708117596">"எதுவும் இல்லை"</string>
<string name="toast_no_application" msgid="1339885974067891667">"கோப்பைத் திறக்க முடியவில்லை"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"சில ஆவணங்களை நீக்க முடியவில்லை"</string>
<string name="share_via" msgid="8966594246261344259">"இதன் வழியாகப் பகிர்"</string>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java b/packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java
index 10baf23..e5f3dc9 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java
@@ -25,6 +25,6 @@ public class KeyguardConstants {
* Turns on debugging information for the whole Keyguard. This is very verbose and should only
* be used temporarily for debugging.
*/
- public static final boolean DEBUG = true;
- public static final boolean DEBUG_SIM_STATES = true;
+ public static final boolean DEBUG = false;
+ public static final boolean DEBUG_SIM_STATES = false;
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
index ac9dc85..d265e0d 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
@@ -50,7 +50,7 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
mAppearAnimationUtils = new AppearAnimationUtils(context);
mDisappearAnimationUtils = new DisappearAnimationUtils(context,
125, 0.6f /* translationScale */,
- 0.6f /* delayScale */, AnimationUtils.loadInterpolator(
+ 0.45f /* delayScale */, AnimationUtils.loadInterpolator(
mContext, android.R.interpolator.fast_out_linear_in));
mDisappearYTranslation = getResources().getDimensionPixelSize(
R.dimen.disappear_y_translation);
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index 59a8ad5..3568429 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -109,7 +109,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
mContext, android.R.interpolator.linear_out_slow_in));
mDisappearAnimationUtils = new DisappearAnimationUtils(context,
125, 1.2f /* translationScale */,
- 0.8f /* delayScale */, AnimationUtils.loadInterpolator(
+ 0.6f /* delayScale */, AnimationUtils.loadInterpolator(
mContext, android.R.interpolator.fast_out_linear_in));
mDisappearYTranslation = getResources().getDimensionPixelSize(
R.dimen.disappear_y_translation);
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 0180a30..9325246 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -387,7 +387,7 @@ public class AccessPoint implements Comparable<AccessPoint> {
} else if (isActive()) {
// This is the active connection on non-passpoint network
summary.append(getSummary(mContext, getDetailedState(),
- networkId == WifiConfiguration.INVALID_NETWORK_ID));
+ mInfo != null && mInfo.isEphemeral()));
} else if (mConfig != null && mConfig.isPasspoint()) {
String format = mContext.getString(R.string.available_via_passpoint);
summary.append(String.format(format, mConfig.providerFriendlyName));
@@ -620,7 +620,8 @@ public class AccessPoint implements Comparable<AccessPoint> {
}
public boolean isEphemeral() {
- return !isSaved() && mNetworkInfo != null && mNetworkInfo.getState() != State.DISCONNECTED;
+ return mInfo != null && mInfo.isEphemeral() &&
+ mNetworkInfo != null && mNetworkInfo.getState() != State.DISCONNECTED;
}
/** Return whether the given {@link WifiInfo} is for this access point. */
@@ -757,7 +758,7 @@ public class AccessPoint implements Comparable<AccessPoint> {
mAccessPointListener.onAccessPointChanged(this);
}
}
-
+
public static String getSummary(Context context, String ssid, DetailedState state,
boolean isEphemeral, String passpointProvider) {
if (state == DetailedState.CONNECTED && ssid == null) {
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index c259573..7c56d63 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -177,10 +177,6 @@
android:label="@*android:string/usb_storage_activity_title"
android:excludeFromRecents="true">
</activity>
- <activity android:name="com.android.internal.app.ExternalMediaFormatActivity"
- android:theme="@*android:style/Theme.Dialog.Alert"
- android:excludeFromRecents="true">
- </activity>
<activity android:name=".tuner.TunerActivity"
android:enabled="false"
diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
index 38ea6e1..0bef513 100644
--- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
+++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
@@ -36,6 +36,7 @@
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:contentDescription="@string/accessibility_brightness"
+ android:importantForAccessibility="no"
systemui:text="@string/status_bar_settings_auto_brightness_label" />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml
index 1a6d34e..91e931d 100644
--- a/packages/SystemUI/res/layout/volume_dialog_row.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_row.xml
@@ -50,6 +50,8 @@
android:layout_below="@id/volume_row_header"
android:layout_toEndOf="@id/volume_row_icon"
android:layout_toStartOf="@+id/volume_settings_button"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
android:paddingEnd="8dp"
android:paddingStart="8dp" />
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 4d6ee79..49b9a36 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -316,8 +316,8 @@
<string name="description_direction_left" msgid="7207478719805562165">"Llisca cap a l\'esquerra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"No t\'interromprà cap so ni cap vibració, tret dels que produeixin les alarmes, els recordatoris, els esdeveniments i les trucades de les persones que especifiquis."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalitza"</string>
- <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos els vídeos, els jocs, les alarmes i la música. Tot i això, encara podràs fer trucades."</string>
- <string name="zen_silence_introduction" msgid="3137882381093271568">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos els vídeos, els jocs, les alarmes i la música."</string>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos els de vídeos, jocs, alarmes i música. Tot i això, encara podràs fer trucades."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos els de vídeos, jocs, alarmes i música."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificacions menys urgents a continuació"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Torna a tocar per obrir"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 895da77..37aa1cc 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -417,7 +417,7 @@
<string name="status_bar_work" msgid="6022553324802866373">"Arbejdsprofil"</string>
<string name="status_bar_airplane" msgid="7057575501472249002">"Flytilstand"</string>
<string name="add_tile" msgid="2995389510240786221">"Tilføj et felt"</string>
- <string name="broadcast_tile" msgid="3894036511763289383">"Felt for udsendelser"</string>
+ <string name="broadcast_tile" msgid="3894036511763289383">"Broadcast-ikon"</string>
<string name="zen_alarm_warning_indef" msgid="3482966345578319605">"Du vil ikke kunne høre din næste alarm <xliff:g id="WHEN">%1$s</xliff:g>, medmindre du slår funktionen fra inden da"</string>
<string name="zen_alarm_warning" msgid="444533119582244293">"Du vil ikke kunne høre din næste alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template" msgid="3980063409350522735">"kl. <xliff:g id="WHEN">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index eab45d9..3f28569 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -316,8 +316,8 @@
<string name="description_direction_left" msgid="7207478719805562165">"Κύλιση προς τα αριστερά για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Δεν θα διακόπτεστε από ήχους και δονήσεις, με εξαίρεση τα ξυπνητήρια, τις υπενθυμίσεις, τα συμβάντα και τους καλούντες που έχετε ορίσει."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Προσαρμογή"</string>
- <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Αυτή η επιλογή αποκλείει ΟΛΟΥΣ τους ήχους και τις δονήσεις, μεταξύ των οποίων των ξυπνητηριών, της μουσικής, των βίντεο και των παιχνιδιών. Θα εξακολουθείτε να είστε σε θέση να πραγματοποιήσετε τηλεφωνικές κλήσεις."</string>
- <string name="zen_silence_introduction" msgid="3137882381093271568">"Αυτή η επιλογή αποκλείει ΟΛΟΥΣ τους ήχους και τις δονήσεις, μεταξύ των οποίων των ξυπνητηριών, της μουσικής, των βίντεο και των παιχνιδιών."</string>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Αυτή η επιλογή αποκλείει όλους τους ήχους και τις δονήσεις, μεταξύ των οποίων των ξυπνητηριών, της μουσικής, των βίντεο και των παιχνιδιών. Θα εξακολουθείτε να είστε σε θέση να πραγματοποιήσετε τηλεφωνικές κλήσεις."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Αυτή η επιλογή αποκλείει όλους τους ήχους και τις δονήσεις, μεταξύ των οποίων των ξυπνητηριών, της μουσικής, των βίντεο και των παιχνιδιών."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Λιγότερο επείγουσες ειδοποιήσεις παρακάτω"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Αγγίξτε ξανά για άνοιγμα"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 3563712..28268ba 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -87,10 +87,8 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Teléfono"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Asistente voz"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloquear"</string>
- <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
- <skip />
- <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
- <skip />
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Botón de desbloqueo, esperando huella digital"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desbloquear sin usar tu huella digital"</string>
<string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string>
<string name="phone_label" msgid="2320074140205331708">"abrir teléfono"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"abrir el asistente de voz"</string>
@@ -316,10 +314,8 @@
<string name="description_direction_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"No te interrumpirán sonidos ni vibraciones, salvo los de las alarmas, los recordatorios, los eventos y las llamadas que especifiques."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string>
- <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
- <skip />
- <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
- <skip />
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Este modo permite bloquear TODOS los sonidos y todas las vibraciones (p. ej., los de alarmas, música, vídeos y juegos). Seguirás pudiendo hacer llamadas de teléfono."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Este modo permite bloquear TODOS los sonidos y todas las vibraciones (p. ej., los de alarmas, música, vídeos y juegos)."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificaciones menos urgente abajo"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Vuelve a tocar para abrir"</string>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index a9edeac..ebc609d 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -87,7 +87,7 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefonoa"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Ahots-laguntza"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desblokeatu"</string>
- <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Desblokeatze-botoia; hatz-markaren zain"</string>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Desblokeatzeko botoia; hatz-markaren zain"</string>
<string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desblokeatu hatz-markaren bidez"</string>
<string name="unlock_label" msgid="8779712358041029439">"desblokeatu"</string>
<string name="phone_label" msgid="2320074140205331708">"ireki telefonoan"</string>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index 0e3d08d..ace9384 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -87,7 +87,7 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Teléfono"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Asistente de voz"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloquear"</string>
- <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Botón de desbloqueo, agardando pola impresión dixital"</string>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Botón de desbloqueo; agardando pola impresión dixital"</string>
<string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desbloquea sen usar a túa impresión dixital"</string>
<string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string>
<string name="phone_label" msgid="2320074140205331708">"abrir teléfono"</string>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index ea39d8b..e32c43e 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -87,10 +87,8 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Հեռախոս"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Ձայնային հուշումներ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Ապակողպել"</string>
- <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
- <skip />
- <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
- <skip />
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Ապակողպման կոճակ, մատնահետքի սպասում"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Ապակողպել չօգտագործելով մատնահետքը"</string>
<string name="unlock_label" msgid="8779712358041029439">"ապակողպել"</string>
<string name="phone_label" msgid="2320074140205331708">"բացել հեռախոսը"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"բացեք ձայնային հուշումը"</string>
@@ -316,10 +314,8 @@
<string name="description_direction_left" msgid="7207478719805562165">"Սահեցրեք ձախ` <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Ոչ մի ձայն և թրթռում չի անհանգստացնի ձեզ, բացառությամբ ձեր ընտրած զարթուցիչներից, հիշեցումներից, իրադարձություններից և զանգողներից:"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Հարմարեցնել"</string>
- <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
- <skip />
- <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
- <skip />
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Այս գործողությունն արգելափակում է ԲՈԼՈՐ ձայներն ու թրթռումները, այդ թվում նաև զարթուցիչների, երաժշտության, տեսանյութերի և խաղերի ձայներն ու թրթռումները: Սակայն կկարողանաք կատարել հեռախոսազանգեր:"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Այս գործողությունն արգելափակում է ԲՈԼՈՐ ձայներն ու թրթռումները, այդ թվում նաև զարթուցիչների, երաժշտության, տեսանյութերի և խաղերի ձայներն ու թրթռումները:"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Պակաս հրատապ ծանուցումները ստորև"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Կրկին հպեք՝ բացելու համար"</string>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 0dbc85e..9b94dd1 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -87,10 +87,8 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"ტელეფონი"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"ხმოვანი დახმარება"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"განბლოკვა"</string>
- <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
- <skip />
- <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
- <skip />
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"განბლოკვის ღილაკი, ელოდება თითის ანაბეჭდს"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"თქვენი თითის ანაბეჭდის გარეშე განბლოკვა"</string>
<string name="unlock_label" msgid="8779712358041029439">"განბლოკვა"</string>
<string name="phone_label" msgid="2320074140205331708">"ტელეფონის გახსნა"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ხმოვანი დახმარების გახსნა"</string>
@@ -316,10 +314,8 @@
<string name="description_direction_left" msgid="7207478719805562165">"გაასრიალეთ მარცხნივ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"თქვენ მიერ მითითებული გაფრთხილებების, შეხსენებების, ღონისძიებებისა და აბონენტების გარდა, არავითარი ხმა და ვიბრაცია არ შეგაწუხებთ."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"მორგება"</string>
- <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
- <skip />
- <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
- <skip />
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ეს ბლოკავს ყველა ხმასა და ვიბრაციას, მათ შორის, მაღვიძარების, მუსიკის, ვიდეოებისა და თამაშების. მიუხედავად ამისა, თქვენ მაინც შეძლებთ სატელეფონო ზარების განხორციელებას."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"ეს ბლოკავს ყველა ხმასა და ვიბრაციას, მათ შორის, მაღვიძარების, მუსიკის, ვიდეოებისა და თამაშების."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"ქვემოთ მითითებულია ნაკლებად სასწრაფო შეტყობინებები"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"შეეხეთ ისევ გასახსნელად"</string>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index 0255fb9..9b20d87 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -314,8 +314,8 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> үшін солға сырғыту."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Дабылдар, еске салғыштар, оқиғалар мен өзіңіз көрсеткен контактілердің қоңырауларынан басқа дыбыстар мен дірілдер мазаламайтын болады."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Реттеу"</string>
- <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Бұл БАРЛЫҚ дыбыстарды және дірілдерді бұғаттайды, соның ішінде, дабылдардыкін, музыканыкін, бейнелердікін және ойындардыкін. Сіз әлі де телефон қоңырауларын шала аласыз."</string>
- <string name="zen_silence_introduction" msgid="3137882381093271568">"Бұл БАРЛЫҚ дыбыстарды және дірілдерді бұғаттайды, соның ішінде, дабылдардыкін, музыканыкін, бейнелердікін және ойындардыкін."</string>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"БАРЛЫҚ, соның ішінде дабылдардың, музыканың, бейнелердің және ойындардың дыбыстары мен дірілдері өшіріледі. Бірақ телефон қоңыраулары шалына береді."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"БАРЛЫҚ, соның ішінде дабылдардың, музыканың, бейнелердің және ойындардың дыбыстары мен дірілдері өшіріледі."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Шұғылдығы азырақ хабарландырулар төменде"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Ашу үшін қайтадан түртіңіз"</string>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index c48b6bb..38e9158 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -111,10 +111,8 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Үн жардамчысы"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Кулпусун ачуу"</string>
- <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
- <skip />
- <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
- <skip />
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Кулпуну ачуу баскычы, манжа изи күтүлүүдө"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Манжа изиңизди колдонбостон эле кулпуну ачыңыз"</string>
<string name="unlock_label" msgid="8779712358041029439">"кулпуну ачуу"</string>
<string name="phone_label" msgid="2320074140205331708">"телефонду ачуу"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"үн жардамчысысын ачуу"</string>
@@ -341,10 +339,8 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> үчүн солго жылмыштырыңыз."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Көрсөтүлгөн эскертүүлөрдөн, эскерткичтерден, окуялардан жана чалуучулардан тышкары башка үндөр жана дирилдөөлөр тынчыңызды албайт."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Ыңгайлаштыруу"</string>
- <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
- <skip />
- <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
- <skip />
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Ушуну менен эскертүүлөрдүн, музыканын, видеолордун жана оюндардын үндөрү жана дирилдөөлөрү сыяктуу нерселердин баары өчүрүлөт. Бирок телефон чала бересиз."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Ушуну менен эскертүүлөрдүн, музыканын, видеолордун жана оюндардын үндөрү жана дирилдөөлөрү сыяктуу нерселердин БААРЫ өчүрүлөт."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Анчейин шашылыш эмес эскертмелер төмөндө"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Ачуу үчүн кайра тийиңиз"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index bbe008f..defdae2 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -89,10 +89,8 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefonas"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Atrakinti"</string>
- <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
- <skip />
- <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
- <skip />
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Atrakinimo mygtukas, laukiama kontrolinio kodo"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Atrakinti nenaudojant kontrolinio kodo"</string>
<string name="unlock_label" msgid="8779712358041029439">"atrakinti"</string>
<string name="phone_label" msgid="2320074140205331708">"atidaryti telefoną"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"atidaryti „Voice Assist“"</string>
@@ -318,10 +316,8 @@
<string name="description_direction_left" msgid="7207478719805562165">"Slyskite į kairę link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Jūsų netrikdys garsai ir vibravimas, išskyrus nurodytų signalų, priminimų, įvykių ir skambintojų garsus ir vibravimą."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Tinkinti"</string>
- <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
- <skip />
- <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
- <skip />
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Taip bus užblokuoti VISI garsai ir vibravimas, įskaitant signalų, muzikos, vaizdo įrašų ir žaidimų garsus ir vibravimą. Vis tiek galėsite skambinti telefonu."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Taip bus užblokuoti VISI garsai ir vibravimas, įskaitant signalų, muzikos, vaizdo įrašų ir žaidimų garsus ir vibravimą."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Mažiau skubūs pranešimai toliau"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Palieskite dar kartą, kad atidarytumėte"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 2350e35..8536dfb 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -88,10 +88,8 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Tālruņa numurs"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Balss palīgs"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Atbloķēt"</string>
- <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
- <skip />
- <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
- <skip />
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Atbloķēšanas poga; tiek gaidīts pirksta nospiedums"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Atbloķēt, neizmantojot pirksta nospiedumu"</string>
<string name="unlock_label" msgid="8779712358041029439">"atbloķēt"</string>
<string name="phone_label" msgid="2320074140205331708">"atvērt tālruni"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"atvērt balss palīgu"</string>
@@ -317,10 +315,8 @@
<string name="description_direction_left" msgid="7207478719805562165">"Velciet pa kreisi, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Jūs netraucēs skaņas un vibrosignāli, ja vien tie nebūs modinātāji, atgādinājumi, pasākumi vai konkrēti zvanītāji, kurus būsiet norādījis."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Pielāgot"</string>
- <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
- <skip />
- <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
- <skip />
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Tiks bloķētas VISAS skaņas un vibrosignāli, tostarp modinātāja, mūzikas, videoklipu un spēļu skaņas un signāli. Jūs joprojām varēsiet veikt tālruņa zvanus."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Tiks bloķētas VISAS skaņas un vibrosignāli, tostarp modinātāja, mūzikas, videoklipu un spēļu skaņas un signāli."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Mazāk steidzami paziņojumi tiek rādīti tālāk"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Pieskarieties vēlreiz, lai atvērtu."</string>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index aef1def..435ed2c 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -87,10 +87,8 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Bantuan Suara"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Buka kunci"</string>
- <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
- <skip />
- <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
- <skip />
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Butang buka kunci, menunggu cap jari"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Buka kunci tanpa menggunakan cap jari"</string>
<string name="unlock_label" msgid="8779712358041029439">"buka kunci"</string>
<string name="phone_label" msgid="2320074140205331708">"buka telefon"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"buka bantuan suara"</string>
@@ -316,10 +314,8 @@
<string name="description_direction_left" msgid="7207478719805562165">"Luncurkan ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Anda tidak akan diganggu oleh bunyi dan getaran kecuali daripada penggera, peringatan, acara dan pemanggil yang anda tentukan."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Peribadikan"</string>
- <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
- <skip />
- <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
- <skip />
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Mod ini menyekat SEMUA bunyi dan getaran, termasuk daripada penggera, muzik, video dan permainan. Anda masih boleh membuat panggilan telefon."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Mod ini menyekat SEMUA bunyi dan getaran, termasuk daripada penggera, muzik, video dan permainan."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Pemberitahuan kurang penting di bawah"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Sentuh sekali lagi untuk membuka"</string>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index af707ba..a83712a 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -87,7 +87,7 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"फोन"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"आवाज सहायता"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"खोल्नुहोस्"</string>
- <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"अनलक बटन फिंगरप्रिन्ट पर्खँदै"</string>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"अनलक बटन, फिंगरप्रिन्ट पर्खँदै"</string>
<string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"तपाईँको फिंगरप्रिन्ट बिना नै अनलक गर्नुहोस्"</string>
<string name="unlock_label" msgid="8779712358041029439">"खोल्नुहोस्"</string>
<string name="phone_label" msgid="2320074140205331708">"फोन खोल्नुहोस्"</string>
@@ -314,7 +314,7 @@
<string name="description_direction_left" msgid="7207478719805562165">"स्लाइड <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि बायाँ।"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"अलार्म, रिमाइन्डर, घटना, र तपाईँले निर्दिष्ट गर्नुहुने कलरहरू देखि बाहेक, आवाज र कम्पनले तपाईँ लाई वाधा गर्ने छैन।"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"अनुकूलन गर्नुहोस्"</string>
- <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"यसले अलार्म, संगीत, भिडियो, र खेलहरू लगायतका सबै ध्वनि र कम्पन निषेध गर्छ। तपाईँ अझै पनि फोन कल गर्न सक्षम हुनुहुन्छ।"</string>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"यसले अलार्म, संगीत, भिडियो, र खेलहरू लगायतका सबै ध्वनि र कम्पन रोक्छ। तपाईँ अझै पनि फोन कल गर्न सक्षम हुनुहुन्छ।"</string>
<string name="zen_silence_introduction" msgid="3137882381093271568">"यसले अलार्म, संगीत, भिडियोहरू र खेलहरूसहित सबै ध्वनिहरू र कम्पनहरूलाई रोक्छ।"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"तल कम जरुरी सूचनाहरू"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 24e2a58..91c2df2 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -88,10 +88,8 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Asistent vocal"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Deblocați"</string>
- <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
- <skip />
- <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
- <skip />
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Buton pentru deblocare, se așteaptă amprenta"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Deblocați fără amprentă"</string>
<string name="unlock_label" msgid="8779712358041029439">"deblocați"</string>
<string name="phone_label" msgid="2320074140205331708">"deschideți telefonul"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"deschideți asistentul vocal"</string>
@@ -317,10 +315,8 @@
<string name="description_direction_left" msgid="7207478719805562165">"Glisaţi spre stânga pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Nu veți fi deranjat(ă) de sunete și vibrații, exceptând alarmele, mementourile, evenimentele și apelanții pe care îi menționați."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizați"</string>
- <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
- <skip />
- <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
- <skip />
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Această opțiune blochează TOATE sunetele și vibrațiile, inclusiv cele ale alarmelor, muzicii, videoclipurilor și jocurilor. Totuși, veți putea iniția apeluri."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Această opțiune blochează TOATE sunetele și vibrațiile, inclusiv cele ale alarmelor, muzicii, videoclipurilor și jocurilor."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificările mai puțin urgente mai jos"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Atingeți din nou pentru a deschide"</string>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index aab90ff..227c4e8 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -88,7 +88,7 @@
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"குரல் உதவி"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"திற"</string>
<string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"திறப்பதற்கான பொத்தான், கைரேகைக்காகக் காத்திருக்கிறது"</string>
- <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"உங்கள் கைரேகையைப் பயன்படுத்தாமல் திறக்கும்"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"உங்கள் கைரேகையைப் பயன்படுத்தாமல் திறக்கவும்"</string>
<string name="unlock_label" msgid="8779712358041029439">"திற"</string>
<string name="phone_label" msgid="2320074140205331708">"ஃபோனைத் திற"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"குரல் உதவியைத் திற"</string>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 0c1c32c..d132933 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -87,10 +87,8 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"فون"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"صوتی معاون"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"غیر مقفل کریں"</string>
- <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
- <skip />
- <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
- <skip />
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"بٹن غیر مقفل کریں، فنگر پرنٹ کا منتظر"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"فنگر پرنٹ استعمال کیے بغیرغیر مقفل کریں"</string>
<string name="unlock_label" msgid="8779712358041029439">"غیر مقفل کریں"</string>
<string name="phone_label" msgid="2320074140205331708">"فون کھولیں"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"صوتی معاون کھولیں"</string>
@@ -316,10 +314,8 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> کیلئے بائیں سلائیڈ کریں۔"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"الارمز، یاد دہانیوں، ایونٹس اور آپ کے متعین کردہ کالرز کے علاوہ، آپ آوازوں اور وائبریشنز سے ڈسٹرب نہیں ہوں گے۔"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"حسب ضرورت بنائیں"</string>
- <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
- <skip />
- <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
- <skip />
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"یہ الارمز، موسیقی، ویڈیوز اور گیمز کی آوازوں اور وائبریشنز سمیت سبھی آوازیں اور وائبریشنز مسدود کر دیتا ہے۔ آپ ابھی بھی فون کالز کر سکیں گے۔"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"یہ الارمز، موسیقی، ویڈیوز اور گیمز کی آوازوں اور وائبریشنز سمیت سبھی آوازیں اور وائبریشنز مسدود کر دیتا ہے۔"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"‎+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>‎"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"کم اہم اطلاعات ذیل میں ہیں"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"کھولنے کیلئے دوبارہ ٹچ کریں"</string>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index b65485d..a971aaf 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -87,10 +87,8 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Ovozli yordam"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Qulfdan chiqarish"</string>
- <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
- <skip />
- <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
- <skip />
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Qulfdan chiqarish tugmasi, barmoq izi kutilmoqda"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Barmoq izisiz qulfdan chiqarish"</string>
<string name="unlock_label" msgid="8779712358041029439">"qulfdan chiqarish"</string>
<string name="phone_label" msgid="2320074140205331708">"telefonni ochish"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ovozli yordamni yoqish"</string>
@@ -316,10 +314,8 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> uchun chapga suring."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Turli ovoz va tebranishlar endi sizni bezovta qilmaydi. Biroq uyg‘otkich signallari, eslatmalar, tadbirlar haqidagi bildirishnomalar va siz tanlagan abonentlardan kelgan qo‘ng‘iroqlar bundan mustasno."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Sozlash"</string>
- <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
- <skip />
- <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
- <skip />
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Bu BARCHA, jumladan signallar, musiqa, videolar va o‘yinlardan keladigan tovush va tebranishlarni to‘sib qo‘yadi. Siz telefon qo‘ng‘iroqlarini bemalol amalga oshirishingiz mumkin."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Bu BARCHA, jumladan, signallar, musiqa, videolar va o‘yinlardan keladigan tovush va tebranishlarni to‘sib qo‘yadi."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Kam ahamiyatli bildirishnomalarni pastda ko‘rsatish"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Ochish uchun yana bosing"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index d77147f..618cf09 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -87,10 +87,8 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"电话"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"语音助理"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"解锁"</string>
- <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
- <skip />
- <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
- <skip />
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"解锁按钮,请用指纹解锁"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"不使用指纹解锁"</string>
<string name="unlock_label" msgid="8779712358041029439">"解锁"</string>
<string name="phone_label" msgid="2320074140205331708">"打开电话"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"打开语音助理"</string>
@@ -318,10 +316,8 @@
<string name="description_direction_left" msgid="7207478719805562165">"向左滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"您将不会受声音和振动的打扰,但闹钟、提醒、活动和您指定的来电者除外。"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"自定义"</string>
- <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
- <skip />
- <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
- <skip />
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"这会阻止所有声音和振动(包括闹钟、音乐、视频和游戏)打扰您。您仍然可以拨打电话。"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"这会阻止所有声音和振动(包括闹钟、音乐、视频和游戏)打扰您。"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"不太紧急的通知会显示在下方"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"再次触摸即可打开"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 367b4a3..19c4e64 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -87,10 +87,8 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"電話"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"語音小幫手"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"解除鎖定"</string>
- <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
- <skip />
- <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
- <skip />
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"解鎖按鈕,正在等待指紋"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"不使用指紋進行解鎖"</string>
<string name="unlock_label" msgid="8779712358041029439">"解除鎖定"</string>
<string name="phone_label" msgid="2320074140205331708">"開啟電話"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"開啟語音小幫手"</string>
@@ -318,10 +316,8 @@
<string name="description_direction_left" msgid="7207478719805562165">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"您不會受到聲音和震動干擾,但鬧鐘、提醒、活動和指定來電者除外。"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"自訂"</string>
- <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
- <skip />
- <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
- <skip />
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"這會封鎖「所有」聲音和震動干擾,包括鬧鐘、音樂、影片和遊戲在內。您仍可以撥打電話。"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"這會封鎖「所有」聲音和震動干擾,包括鬧鐘、音樂、影片和遊戲在內。"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"還有 <xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g> 則通知"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"較不緊急的通知會顯示在下方"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"再次輕觸即可開啟"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 005077f..155f5ea 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -583,7 +583,7 @@
<dimen name="managed_profile_toast_padding">4dp</dimen>
<!-- Thickness of the assist disclosure beams -->
- <dimen name="assist_disclosure_thickness">4dp</dimen>
+ <dimen name="assist_disclosure_thickness">3dp</dimen>
<!-- Thickness of the shadows of the assist disclosure beams -->
<dimen name="assist_disclosure_shadow_thickness">1.5dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
index 585f9ba..c3a8f2e 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
@@ -32,6 +32,7 @@ import android.graphics.PorterDuffXfermode;
import android.os.Handler;
import android.view.View;
import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AnimationUtils;
/**
@@ -166,6 +167,7 @@ public class AssistDisclosure {
super.onAttachedToWindow();
startAnimation();
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_ASSIST_READING_CONTEXT);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 7838119..51d0bf1 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -125,16 +125,13 @@ public class AssistManager {
}
}
- public void onGestureInvoked(boolean vibrate) {
+ public void onGestureInvoked() {
if (mAssistComponent == null) {
return;
}
- if (vibrate) {
- vibrate();
- }
final boolean isService = isAssistantService();
- if (isService || !isVoiceSessionRunning()) {
+ if (!isService || !isVoiceSessionRunning()) {
showOrb();
mView.postDelayed(mHideRunnable, isService
? TIMEOUT_SERVICE
@@ -230,10 +227,6 @@ public class AssistManager {
mAssistUtils.launchVoiceAssistFromKeyguard();
}
- private boolean getVoiceInteractorSupportsAssistGesture() {
- return mAssistUtils.activeServiceSupportsAssistGesture();
- }
-
public boolean canVoiceAssistBeLaunchedFromKeyguard() {
return mAssistUtils.activeServiceSupportsLaunchFromKeyguard();
}
@@ -290,10 +283,6 @@ public class AssistManager {
v.setImageDrawable(null);
}
- private void vibrate() {
- mView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
- }
-
private boolean isAssistantService() {
return mAssistComponent == null ?
false : mAssistComponent.equals(getVoiceInteractorComponentName());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 4b1453d..2ded919 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -472,6 +472,7 @@ public class QSPanel extends ViewGroup {
rows = r + 1;
}
+ View previousView = mBrightnessView;
for (TileRecord record : mRecords) {
if (record.tileView.setDual(record.tile.supportsDualTargets())) {
record.tileView.handleStateChanged(record.tile.getState());
@@ -480,6 +481,7 @@ public class QSPanel extends ViewGroup {
final int cw = record.row == 0 ? mLargeCellWidth : mCellWidth;
final int ch = record.row == 0 ? mLargeCellHeight : mCellHeight;
record.tileView.measure(exactly(cw), exactly(ch));
+ previousView = record.tileView.updateAccessibilityOrder(previousView);
}
int h = rows == 0 ? brightnessHeight : (getRowTop(rows) + mPanelPaddingBottom);
if (mFooter.hasFooter()) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index af9d3a5..6d26a3b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -83,6 +83,7 @@ public class QSTileView extends ViewGroup {
setClipChildren(false);
mTopBackgroundView = new View(context);
+ mTopBackgroundView.setId(View.generateViewId());
addView(mTopBackgroundView);
mIcon = createIcon();
@@ -95,8 +96,8 @@ public class QSTileView extends ViewGroup {
addView(mDivider);
setClickable(true);
-
updateTopPadding();
+ setId(View.generateViewId());
}
private void updateTopPadding() {
@@ -137,7 +138,7 @@ public class QSTileView extends ViewGroup {
final Resources res = mContext.getResources();
if (mDual) {
mDualLabel = new QSDualTileLabel(mContext);
- mDualLabel.setId(android.R.id.title);
+ mDualLabel.setId(View.generateViewId());
mDualLabel.setBackgroundResource(R.drawable.btn_borderless_rect);
mDualLabel.setFirstLineCaret(mContext.getDrawable(R.drawable.qs_dual_tile_caret));
mDualLabel.setTextColor(mContext.getColor(R.color.qs_tile_text));
@@ -155,9 +156,9 @@ public class QSTileView extends ViewGroup {
mDualLabel.setContentDescription(labelDescription);
}
addView(mDualLabel);
+ mDualLabel.setAccessibilityTraversalAfter(mTopBackgroundView.getId());
} else {
mLabel = new TextView(mContext);
- mLabel.setId(android.R.id.title);
mLabel.setTextColor(mContext.getColor(R.color.qs_tile_text));
mLabel.setGravity(Gravity.CENTER_HORIZONTAL);
mLabel.setMinLines(2);
@@ -328,6 +329,26 @@ public class QSTileView extends ViewGroup {
mHandler.obtainMessage(H.STATE_CHANGED, state).sendToTarget();
}
+ /**
+ * Update the accessibility order for this view.
+ *
+ * @param previousView the view which should be before this one
+ * @return the last view in this view which is accessible
+ */
+ public View updateAccessibilityOrder(View previousView) {
+ View firstView;
+ View lastView;
+ if (mDual) {
+ lastView = mDualLabel;
+ firstView = mTopBackgroundView;
+ } else {
+ firstView = this;
+ lastView = this;
+ }
+ firstView.setAccessibilityTraversalAfter(previousView.getId());
+ return lastView;
+ }
+
private class H extends Handler {
private static final int STATE_CHANGED = 1;
public H() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 1b74eb6..359ed5f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -28,6 +28,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
import android.view.ViewGroup;
+import android.widget.Toast;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.Prefs;
@@ -98,6 +99,14 @@ public class DndTile extends QSTile<QSTile.BooleanState> {
@Override
public void handleClick() {
+ if (mController.isVolumeRestricted()) {
+ // Collapse the panels, so the user can see the toast.
+ mHost.collapsePanels();
+ Toast.makeText(mContext, mContext.getString(
+ com.android.internal.R.string.error_message_change_not_allowed),
+ Toast.LENGTH_LONG).show();
+ return;
+ }
mDisable.setAllowAnimation(true);
mDisableTotalSilence.setAllowAnimation(true);
MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
diff --git a/packages/SystemUI/src/com/android/systemui/settings/ToggleSeekBar.java b/packages/SystemUI/src/com/android/systemui/settings/ToggleSeekBar.java
index a0a5561..8829794 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/ToggleSeekBar.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/ToggleSeekBar.java
@@ -19,9 +19,13 @@ package com.android.systemui.settings;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
+import android.view.View;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.SeekBar;
public class ToggleSeekBar extends SeekBar {
+ private String mAccessibilityLabel;
+
public ToggleSeekBar(Context context) {
super(context);
}
@@ -42,4 +46,16 @@ public class ToggleSeekBar extends SeekBar {
return super.onTouchEvent(event);
}
+
+ public void setAccessibilityLabel(String label) {
+ mAccessibilityLabel = label;
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ if (mAccessibilityLabel != null) {
+ info.setText(mAccessibilityLabel);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
index d247711..b263707 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
@@ -43,7 +43,7 @@ public class ToggleSlider extends RelativeLayout {
private boolean mTracking;
private CompoundButton mToggle;
- private SeekBar mSlider;
+ private ToggleSeekBar mSlider;
private TextView mLabel;
private ToggleSlider mMirror;
@@ -69,13 +69,13 @@ public class ToggleSlider extends RelativeLayout {
mToggle = (CompoundButton) findViewById(R.id.toggle);
mToggle.setOnCheckedChangeListener(mCheckListener);
- mSlider = (SeekBar) findViewById(R.id.slider);
+ mSlider = (ToggleSeekBar) findViewById(R.id.slider);
mSlider.setOnSeekBarChangeListener(mSeekListener);
mLabel = (TextView) findViewById(R.id.label);
mLabel.setText(a.getString(R.styleable.ToggleSlider_text));
- setLabelFor(R.id.slider); // use our a11y text to annotate, not replace, the slider's
+ mSlider.setAccessibilityLabel(getContentDescription().toString());
a.recycle();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 8d20772..6ad0ef9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -303,6 +303,7 @@ public abstract class BaseStatusBar extends SystemUI implements
try {
ActivityManagerNative.getDefault()
.keyguardWaitingForActivityDrawn();
+ ActivityManagerNative.getDefault().resumeAppSwitches();
} catch (RemoteException e) {
}
}
@@ -315,7 +316,9 @@ public abstract class BaseStatusBar extends SystemUI implements
animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
true /* force */);
visibilityChanged(false);
+ mAssistManager.hideAssist();
}
+
// Wait for activity start.
return handled;
}
@@ -1620,7 +1623,13 @@ public abstract class BaseStatusBar extends SystemUI implements
boolean clearNotificationEffects = !isPanelFullyCollapsed() &&
(mShowLockscreenNotifications ||
(mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED));
- mBarService.onPanelRevealed(clearNotificationEffects);
+ int notificationLoad = mNotificationData.getActiveNotifications().size();
+ if (mHeadsUpManager.hasPinnedHeadsUp() && isPanelFullyCollapsed()) {
+ notificationLoad = 1;
+ } else {
+ MetricsLogger.histogram(mContext, "note_load", notificationLoad);
+ }
+ mBarService.onPanelRevealed(clearNotificationEffects, notificationLoad);
} else {
mBarService.onPanelHidden();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 5a4acb4..da1f03e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -224,7 +224,10 @@ public class SignalClusterView
public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
String description, boolean isWide, int subId) {
- PhoneState state = getOrInflateState(subId);
+ PhoneState state = getState(subId);
+ if (state == null) {
+ return;
+ }
state.mMobileVisible = statusIcon.visible && !mBlockMobile;
state.mMobileStrengthId = statusIcon.icon;
state.mMobileTypeId = statusType;
@@ -281,13 +284,14 @@ public class SignalClusterView
return true;
}
- private PhoneState getOrInflateState(int subId) {
+ private PhoneState getState(int subId) {
for (PhoneState state : mPhoneStates) {
if (state.mSubId == subId) {
return state;
}
}
- return inflatePhoneState(subId);
+ Log.e(TAG, "Unexpected subscription " + subId);
+ return null;
}
private PhoneState inflatePhoneState(int subId) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index f5fdf48..6bcb766 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -213,7 +213,8 @@ public class LockIcon extends KeyguardAffordanceView {
return R.drawable.lockscreen_fingerprint_fp_to_error_state_animation;
} else if (oldState == STATE_FINGERPRINT_ERROR && newState == STATE_FINGERPRINT) {
return R.drawable.lockscreen_fingerprint_error_state_to_fp_animation;
- } else if (oldState == STATE_FINGERPRINT && newState == STATE_LOCK_OPEN) {
+ } else if (oldState == STATE_FINGERPRINT && newState == STATE_LOCK_OPEN
+ && !mUnlockMethodCache.isCurrentlyInsecure()) {
return R.drawable.lockscreen_fingerprint_draw_off_animation;
} else if (newState == STATE_FINGERPRINT && !oldScreenOn && screenOn) {
return R.drawable.lockscreen_fingerprint_draw_on_animation;
@@ -225,14 +226,14 @@ public class LockIcon extends KeyguardAffordanceView {
private int getState() {
boolean fingerprintRunning =
KeyguardUpdateMonitor.getInstance(mContext).isFingerprintDetectionRunning();
- if (mTransientFpError) {
+ if (mUnlockMethodCache.isCurrentlyInsecure()) {
+ return STATE_LOCK_OPEN;
+ } else if (mTransientFpError) {
return STATE_FINGERPRINT_ERROR;
} else if (fingerprintRunning) {
return STATE_FINGERPRINT;
} else if (mUnlockMethodCache.isFaceUnlockRunning()) {
return STATE_FACE_UNLOCK;
- } else if (mUnlockMethodCache.isCurrentlyInsecure()) {
- return STATE_LOCK_OPEN;
} else {
return STATE_LOCKED;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index cf0d670..094b9b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -721,7 +721,6 @@ public class NotificationPanelView extends PanelView implements
if (mListenForHeadsUp && !mHeadsUpTouchHelper.isTrackingHeadsUp()
&& mHeadsUpTouchHelper.onInterceptTouchEvent(event)) {
mIsExpansionFromHeadsUp = true;
- MetricsLogger.count(mContext, COUNTER_PANEL_OPEN, 1);
MetricsLogger.count(mContext, COUNTER_PANEL_OPEN_PEEK, 1);
}
if ((!mIsExpanding || mHintAnimationRunning)
@@ -1126,38 +1125,41 @@ public class NotificationPanelView extends PanelView implements
};
private void animateKeyguardStatusBarOut() {
- mKeyguardStatusBar.animate()
- .alpha(0f)
- .setStartDelay(mStatusBar.isKeyguardFadingAway()
- ? mStatusBar.getKeyguardFadingAwayDelay()
- : 0)
- .setDuration(mStatusBar.isKeyguardFadingAway()
- ? mStatusBar.getKeyguardFadingAwayDuration() / 2
- : StackStateAnimator.ANIMATION_DURATION_STANDARD)
- .setInterpolator(PhoneStatusBar.ALPHA_OUT)
- .setUpdateListener(mStatusBarAnimateAlphaListener)
- .withEndAction(mAnimateKeyguardStatusBarInvisibleEndRunnable)
- .start();
+ ValueAnimator anim = ValueAnimator.ofFloat(mKeyguardStatusBar.getAlpha(), 0f);
+ anim.addUpdateListener(mStatusBarAnimateAlphaListener);
+ anim.setStartDelay(mStatusBar.isKeyguardFadingAway()
+ ? mStatusBar.getKeyguardFadingAwayDelay()
+ : 0);
+ anim.setDuration(mStatusBar.isKeyguardFadingAway()
+ ? mStatusBar.getKeyguardFadingAwayDuration() / 2
+ : StackStateAnimator.ANIMATION_DURATION_STANDARD);
+ anim.setInterpolator(mDozeAnimationInterpolator);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mAnimateKeyguardStatusBarInvisibleEndRunnable.run();
+ }
+ });
+ anim.start();
}
private final ValueAnimator.AnimatorUpdateListener mStatusBarAnimateAlphaListener =
new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
- mKeyguardStatusBarAnimateAlpha = mKeyguardStatusBar.getAlpha();
+ mKeyguardStatusBarAnimateAlpha = (float) animation.getAnimatedValue();
+ updateHeaderKeyguardAlpha();
}
};
private void animateKeyguardStatusBarIn(long duration) {
mKeyguardStatusBar.setVisibility(View.VISIBLE);
mKeyguardStatusBar.setAlpha(0f);
- mKeyguardStatusBar.animate()
- .alpha(1f)
- .setStartDelay(0)
- .setDuration(duration)
- .setInterpolator(mDozeAnimationInterpolator)
- .setUpdateListener(mStatusBarAnimateAlphaListener)
- .start();
+ ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
+ anim.addUpdateListener(mStatusBarAnimateAlphaListener);
+ anim.setDuration(duration);
+ anim.setInterpolator(mDozeAnimationInterpolator);
+ anim.start();
}
private final Runnable mAnimateKeyguardBottomAreaInvisibleEndRunnable = new Runnable() {
@@ -1716,12 +1718,16 @@ public class NotificationPanelView extends PanelView implements
return alpha;
}
- private void updateHeaderKeyguard() {
+ private void updateHeaderKeyguardAlpha() {
float alphaQsExpansion = 1 - Math.min(1, getQsExpansionFraction() * 2);
mKeyguardStatusBar.setAlpha(Math.min(getKeyguardContentsAlpha(), alphaQsExpansion)
* mKeyguardStatusBarAnimateAlpha);
mKeyguardStatusBar.setVisibility(mKeyguardStatusBar.getAlpha() != 0f
&& !mDozing ? VISIBLE : INVISIBLE);
+ }
+
+ private void updateHeaderKeyguard() {
+ updateHeaderKeyguardAlpha();
setQsTranslation(mQsExpansionHeight);
}
@@ -1811,6 +1817,7 @@ public class NotificationPanelView extends PanelView implements
|| mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
mAfforanceHelper.animateHideLeftRightIcon();
}
+ mNotificationStackScroller.onPanelTrackingStarted();
}
@Override
@@ -1820,6 +1827,7 @@ public class NotificationPanelView extends PanelView implements
mNotificationStackScroller.setOverScrolledPixels(
0.0f, true /* onTop */, true /* animate */);
}
+ mNotificationStackScroller.onPanelTrackingStopped();
if (expand && (mStatusBar.getBarState() == StatusBarState.KEYGUARD
|| mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED)) {
if (!mHintAnimationRunning) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 39a06aa..9343172 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -834,8 +834,10 @@ public abstract class PanelView extends FrameLayout {
}
} else if (!isFullyCollapsed() && !mTracking && !mClosing) {
cancelHeightAnimator();
- mClosing = true;
notifyExpandingStarted();
+
+ // Set after notifyExpandingStarted, as notifyExpandingStarted resets the closing state.
+ mClosing = true;
if (delayed) {
mNextCollapseSpeedUpFactor = speedUpFactor;
postDelayed(mFlingCollapseRunnable, 120);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 7f87485..a637e24 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -106,6 +106,7 @@ import com.android.systemui.EventLogConstants;
import com.android.systemui.EventLogTags;
import com.android.systemui.Prefs;
import com.android.systemui.R;
+import com.android.systemui.SwipeHelper;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.doze.DozeHost;
import com.android.systemui.doze.DozeLog;
@@ -633,7 +634,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
R.layout.super_status_bar, null);
- mStatusBarWindow.mService = this;
+ mStatusBarWindow.setService(this);
mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
@@ -676,8 +677,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mNotificationPanelDebugText.setVisibility(View.VISIBLE);
}
- updateShowSearchHoldoff();
-
try {
boolean showNav = mWindowManagerService.hasNavigationBar();
if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
@@ -1013,11 +1012,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
return mStatusBarWindow;
}
- public void invokeAssistGesture(boolean vibrate) {
- mHandler.removeCallbacks(mInvokeAssist);
- mAssistManager.onGestureInvoked(vibrate);
- }
-
public int getStatusBarHeight() {
if (mNaturalBarHeight < 0) {
final Resources res = mContext.getResources();
@@ -1044,31 +1038,28 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
};
- private int mShowSearchHoldoff = 0;
- private Runnable mInvokeAssist = new Runnable() {
- public void run() {
+ private final View.OnLongClickListener mLongPressHomeListener
+ = new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ if (shouldDisableNavbarGestures()) {
+ return false;
+ }
mAssistManager.prepareBeforeInvocation();
- invokeAssistGesture(true /* vibrate */);
+ mAssistManager.onGestureInvoked();
awakenDreams();
if (mNavigationBarView != null) {
mNavigationBarView.abortCurrentGesture();
}
+ return true;
}
};
- View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
+ private final View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- if (!shouldDisableNavbarGestures()) {
- mHandler.removeCallbacks(mInvokeAssist);
- mHandler.postDelayed(mInvokeAssist, mShowSearchHoldoff);
- }
- break;
-
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- mHandler.removeCallbacks(mInvokeAssist);
awakenDreams();
break;
}
@@ -1096,6 +1087,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mNavigationBarView.getBackButton().setLongClickable(true);
mNavigationBarView.getBackButton().setOnLongClickListener(mLongPressBackRecentsListener);
mNavigationBarView.getHomeButton().setOnTouchListener(mHomeActionListener);
+ mNavigationBarView.getHomeButton().setOnLongClickListener(mLongPressHomeListener);
mAssistManager.onConfigurationChanged();
}
@@ -1188,6 +1180,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
notification.getKey());
notification.getNotification().fullScreenIntent.send();
shadeEntry.notifyFullScreenIntentLaunched();
+ MetricsLogger.count(mContext, "note_fullscreen", 1);
} catch (PendingIntent.CanceledException e) {
}
}
@@ -1236,10 +1229,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
}
- private void updateShowSearchHoldoff() {
- mShowSearchHoldoff = ViewConfiguration.getLongPressTimeout();
- }
-
private void updateNotificationShade() {
if (mStackScroller == null) return;
@@ -2922,7 +2911,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
updateResources();
repositionNavigationBar();
- updateShowSearchHoldoff();
updateRowStates();
mIconController.updateResources();
mScreenPinningRequest.onConfigurationChanged();
@@ -2944,6 +2932,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (mZenModeController != null) {
mZenModeController.setUserId(mCurrentUserId);
}
+ if (mSecurityController != null) {
+ mSecurityController.onUserSwitched(mCurrentUserId);
+ }
}
private void resetUserSetupObserver() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 634270c..0e22aa8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -53,7 +53,7 @@ public class StatusBarWindowView extends FrameLayout {
private int mRightInset = 0;
- PhoneStatusBar mService;
+ private PhoneStatusBar mService;
private final Paint mTransparentSrcPaint = new Paint();
public StatusBarWindowView(Context context, AttributeSet attrs) {
@@ -124,14 +124,22 @@ public class StatusBarWindowView extends FrameLayout {
}
@Override
- protected void onAttachedToWindow () {
- super.onAttachedToWindow();
-
+ protected void onFinishInflate() {
+ super.onFinishInflate();
mStackScrollLayout = (NotificationStackScrollLayout) findViewById(
R.id.notification_stack_scroller);
mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel);
- mDragDownHelper = new DragDownHelper(getContext(), this, mStackScrollLayout, mService);
mBrightnessMirror = findViewById(R.id.brightness_mirror);
+ }
+
+ public void setService(PhoneStatusBar service) {
+ mService = service;
+ mDragDownHelper = new DragDownHelper(getContext(), this, mStackScrollLayout, mService);
+ }
+
+ @Override
+ protected void onAttachedToWindow () {
+ super.onAttachedToWindow();
// We really need to be able to animate while window animations are going on
// so that activities may be started asynchronously from panel animations
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 98bbe7c..63f5711 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -29,6 +29,7 @@ import android.view.View;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
+import com.android.internal.logging.MetricsLogger;
import com.android.systemui.R;
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.NotificationData;
@@ -82,6 +83,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
private final View mStatusBarWindowView;
private final int mStatusBarHeight;
private final int mNotificationsTopPadding;
+ private final Context mContext;
private PhoneStatusBar mBar;
private int mSnoozeLengthMs;
private ContentObserver mSettingsObserver;
@@ -101,7 +103,8 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
private boolean mIsObserving;
public HeadsUpManager(final Context context, View statusBarWindowView) {
- Resources resources = context.getResources();
+ mContext = context;
+ Resources resources = mContext.getResources();
mTouchAcceptanceDelay = resources.getInteger(R.integer.touch_acceptance_delay);
mSnoozedPackages = new ArrayMap<>();
mDefaultSnoozeLengthMs = resources.getInteger(R.integer.heads_up_default_snooze_length_ms);
@@ -165,6 +168,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
*/
public void showNotification(NotificationData.Entry headsUp) {
if (DEBUG) Log.v(TAG, "showNotification");
+ MetricsLogger.count(mContext, "note_peek", 1);
addHeadsUpEntry(headsUp);
updateNotification(headsUp, true);
headsUp.setInterruption();
@@ -522,7 +526,6 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
});
}
-
/**
* This represents a notification and how long it is in a heads up mode. It also manages its
* lifecycle automatically when created.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 6bc51fa..4c99792 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -57,7 +57,7 @@ public class KeyButtonView extends ImageView {
if (isLongClickable()) {
// Just an old-fashioned ImageView
performLongClick();
- } else {
+ } else if (mSupportsLongpress) {
sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
}
@@ -92,7 +92,7 @@ public class KeyButtonView extends ImageView {
super.onInitializeAccessibilityNodeInfo(info);
if (mCode != 0) {
info.addAction(new AccessibilityNodeInfo.AccessibilityAction(ACTION_CLICK, null));
- if (mSupportsLongpress) {
+ if (mSupportsLongpress || isLongClickable()) {
info.addAction(
new AccessibilityNodeInfo.AccessibilityAction(ACTION_LONG_CLICK, null));
}
@@ -115,7 +115,7 @@ public class KeyButtonView extends ImageView {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
playSoundEffect(SoundEffectConstants.CLICK);
return true;
- } else if (action == ACTION_LONG_CLICK && mCode != 0 && mSupportsLongpress) {
+ } else if (action == ACTION_LONG_CLICK && mCode != 0) {
sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
sendEvent(KeyEvent.ACTION_UP, 0);
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
@@ -144,10 +144,8 @@ public class KeyButtonView extends ImageView {
// Provide the same haptic feedback that the system offers for virtual keys.
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
}
- if (mSupportsLongpress) {
- removeCallbacks(mCheckLongPress);
- postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
- }
+ removeCallbacks(mCheckLongPress);
+ postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
break;
case MotionEvent.ACTION_MOVE:
x = (int)ev.getX();
@@ -162,9 +160,7 @@ public class KeyButtonView extends ImageView {
if (mCode != 0) {
sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
}
- if (mSupportsLongpress) {
- removeCallbacks(mCheckLongPress);
- }
+ removeCallbacks(mCheckLongPress);
break;
case MotionEvent.ACTION_UP:
final boolean doIt = isPressed();
@@ -183,9 +179,7 @@ public class KeyButtonView extends ImageView {
performClick();
}
}
- if (mSupportsLongpress) {
- removeCallbacks(mCheckLongPress);
- }
+ removeCallbacks(mCheckLongPress);
break;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index b21767b..b1c650e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -291,6 +291,7 @@ public class MobileSignalController extends SignalController<
notifyListenersIfNecessary();
} else if (action.equals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
updateDataSim();
+ notifyListenersIfNecessary();
}
}
@@ -308,7 +309,6 @@ public class MobileSignalController extends SignalController<
// for long.
mCurrentState.dataSim = true;
}
- notifyListenersIfNecessary();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 1ba87da..ff0e8a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -110,6 +110,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
// The current user ID.
private int mCurrentUserId;
+ private OnSubscriptionsChangedListener mSubscriptionListener;
+
// Handler that all broadcasts are received on.
private final Handler mReceiverHandler;
// Handler that all callbacks are made on.
@@ -179,6 +181,9 @@ public class NetworkControllerImpl extends BroadcastReceiver
for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
mobileSignalController.registerListener();
}
+ if (mSubscriptionListener == null) {
+ mSubscriptionListener = new SubListener();
+ }
mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
// broadcasts
@@ -422,7 +427,6 @@ public class NetworkControllerImpl extends BroadcastReceiver
: lhs.getSimSlotIndex() - rhs.getSimSlotIndex();
}
});
- mCallbackHandler.setSubs(subscriptions);
mCurrentSubscriptions = subscriptions;
HashMap<Integer, MobileSignalController> cachedControllers =
@@ -455,6 +459,9 @@ public class NetworkControllerImpl extends BroadcastReceiver
cachedControllers.get(key).unregisterListener();
}
}
+ mCallbackHandler.setSubs(subscriptions);
+ notifyAllListeners();
+
// There may be new MobileSignalControllers around, make sure they get the current
// inet condition and airplane mode.
pushConnectivityToSignals();
@@ -724,13 +731,12 @@ public class NetworkControllerImpl extends BroadcastReceiver
return info;
}
- private final OnSubscriptionsChangedListener mSubscriptionListener =
- new OnSubscriptionsChangedListener() {
+ private class SubListener extends OnSubscriptionsChangedListener {
@Override
public void onSubscriptionsChanged() {
updateMobileControllers();
- };
- };
+ }
+ }
/**
* Used to register listeners from the BG Looper, this way the PhoneStateListeners that
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index 962000a..b505d9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -64,6 +64,7 @@ public class SecurityControllerImpl implements SecurityController {
private SparseArray<VpnConfig> mCurrentVpns = new SparseArray<>();
private int mCurrentUserId;
+ private int mVpnUserId;
public SecurityControllerImpl(Context context) {
mContext = context;
@@ -78,7 +79,7 @@ public class SecurityControllerImpl implements SecurityController {
// TODO: re-register network callback on user change.
mConnectivityManager.registerNetworkCallback(REQUEST, mNetworkCallback);
- mCurrentUserId = ActivityManager.getCurrentUser();
+ onUserSwitched(ActivityManager.getCurrentUser());
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -123,9 +124,9 @@ public class SecurityControllerImpl implements SecurityController {
@Override
public String getPrimaryVpnName() {
- VpnConfig cfg = mCurrentVpns.get(mCurrentUserId);
+ VpnConfig cfg = mCurrentVpns.get(mVpnUserId);
if (cfg != null) {
- return getNameForVpnConfig(cfg, new UserHandle(mCurrentUserId));
+ return getNameForVpnConfig(cfg, new UserHandle(mVpnUserId));
} else {
return null;
}
@@ -133,8 +134,8 @@ public class SecurityControllerImpl implements SecurityController {
@Override
public String getProfileVpnName() {
- for (UserInfo profile : mUserManager.getProfiles(mCurrentUserId)) {
- if (profile.id == mCurrentUserId) {
+ for (UserInfo profile : mUserManager.getProfiles(mVpnUserId)) {
+ if (profile.id == mVpnUserId) {
continue;
}
VpnConfig cfg = mCurrentVpns.get(profile.id);
@@ -147,7 +148,7 @@ public class SecurityControllerImpl implements SecurityController {
@Override
public boolean isVpnEnabled() {
- for (UserInfo profile : mUserManager.getProfiles(mCurrentUserId)) {
+ for (UserInfo profile : mUserManager.getProfiles(mVpnUserId)) {
if (mCurrentVpns.get(profile.id) != null) {
return true;
}
@@ -172,6 +173,12 @@ public class SecurityControllerImpl implements SecurityController {
@Override
public void onUserSwitched(int newUserId) {
mCurrentUserId = newUserId;
+ if (mUserManager.getUserInfo(newUserId).isRestricted()) {
+ // VPN for a restricted profile is routed through its owner user
+ mVpnUserId = UserHandle.USER_OWNER;
+ } else {
+ mVpnUserId = mCurrentUserId;
+ }
fireCallbacks();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
index 9d84a85..b2df40a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
@@ -36,6 +36,7 @@ public interface ZenModeController {
ComponentName getEffectsSuppressor();
boolean isCountdownConditionSupported();
int getCurrentUser();
+ boolean isVolumeRestricted();
public static class Callback {
public void onZenChanged(int zen) {}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
index 5b80ac2..c07f1a8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
@@ -29,6 +29,7 @@ import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
import android.service.notification.Condition;
@@ -57,6 +58,7 @@ public class ZenModeControllerImpl implements ZenModeController {
private final LinkedHashMap<Uri, Condition> mConditions = new LinkedHashMap<Uri, Condition>();
private final AlarmManager mAlarmManager;
private final SetupObserver mSetupObserver;
+ private final UserManager mUserManager;
private int mUserId;
private boolean mRequesting;
@@ -84,6 +86,13 @@ public class ZenModeControllerImpl implements ZenModeController {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
mSetupObserver = new SetupObserver(handler);
mSetupObserver.register();
+ mUserManager = context.getSystemService(UserManager.class);
+ }
+
+ @Override
+ public boolean isVolumeRestricted() {
+ return mUserManager.hasUserRestriction(UserManager.DISALLOW_ADJUST_VOLUME,
+ new UserHandle(mUserId));
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index f98840b..7040864 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -163,6 +163,7 @@ public class NotificationStackScrollLayout extends ViewGroup
private boolean mChildrenUpdateRequested;
private SpeedBumpView mSpeedBumpView;
private boolean mIsExpansionChanging;
+ private boolean mPanelTracking;
private boolean mExpandingNotification;
private boolean mExpandedInThisMotion;
private boolean mScrollingEnabled;
@@ -1513,7 +1514,7 @@ public class NotificationStackScrollLayout extends ViewGroup
}
if (mExpandedInThisMotion) {
return RUBBER_BAND_FACTOR_AFTER_EXPAND;
- } else if (mIsExpansionChanging) {
+ } else if (mIsExpansionChanging || mPanelTracking) {
return RUBBER_BAND_FACTOR_ON_PANEL_EXPAND;
} else if (mScrolledToTopOnFirstDown) {
return 1.0f;
@@ -1527,7 +1528,7 @@ public class NotificationStackScrollLayout extends ViewGroup
* overscroll view (e.g. expand QS).
*/
private boolean isRubberbanded(boolean onTop) {
- return !onTop || mExpandedInThisMotion || mIsExpansionChanging
+ return !onTop || mExpandedInThisMotion || mIsExpansionChanging || mPanelTracking
|| !mScrolledToTopOnFirstDown;
}
@@ -2249,6 +2250,13 @@ public class NotificationStackScrollLayout extends ViewGroup
}
}
+ public void onPanelTrackingStarted() {
+ mPanelTracking = true;
+ }
+ public void onPanelTrackingStopped() {
+ mPanelTracking = false;
+ }
+
public void resetScrollPosition() {
mScroller.abortAnimation();
mOwnScrollY = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index d360875..92cfaa1 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -318,11 +318,14 @@ public class StorageNotification extends SystemUI {
private Notification onVolumeMounted(VolumeInfo vol) {
final VolumeRecord rec = mStorageManager.findRecordByUuid(vol.getFsUuid());
+ final DiskInfo disk = vol.getDisk();
- // Don't annoy when user dismissed in past
- if (rec.isSnoozed()) return null;
+ // Don't annoy when user dismissed in past. (But make sure the disk is adoptable; we
+ // used to allow snoozing non-adoptable disks too.)
+ if (rec.isSnoozed() && disk.isAdoptable()) {
+ return null;
+ }
- final DiskInfo disk = vol.getDisk();
if (disk.isAdoptable() && !rec.isInited()) {
final CharSequence title = disk.getDescription();
final CharSequence text = mContext.getString(
@@ -346,7 +349,7 @@ public class StorageNotification extends SystemUI {
R.string.ext_media_ready_notification_message, disk.getDescription());
final PendingIntent browseIntent = buildBrowsePendingIntent(vol);
- return buildNotificationBuilder(vol, title, text)
+ final Notification.Builder builder = buildNotificationBuilder(vol, title, text)
.addAction(new Action(R.drawable.ic_folder_24dp,
mContext.getString(R.string.ext_media_browse_action),
browseIntent))
@@ -354,10 +357,14 @@ public class StorageNotification extends SystemUI {
mContext.getString(R.string.ext_media_unmount_action),
buildUnmountPendingIntent(vol)))
.setContentIntent(browseIntent)
- .setDeleteIntent(buildSnoozeIntent(vol.getFsUuid()))
.setCategory(Notification.CATEGORY_SYSTEM)
- .setPriority(Notification.PRIORITY_LOW)
- .build();
+ .setPriority(Notification.PRIORITY_LOW);
+ // Non-adoptable disks can't be snoozed.
+ if (disk.isAdoptable()) {
+ builder.setDeleteIntent(buildSnoozeIntent(vol.getFsUuid()));
+ }
+
+ return builder.build();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
index 81461bd..f432808 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
@@ -57,7 +57,7 @@ public class SegmentedButtons extends LinearLayout {
return mSelectedValue;
}
- public void setSelectedValue(Object value) {
+ public void setSelectedValue(Object value, boolean fromClick) {
if (Objects.equals(value, mSelectedValue)) return;
mSelectedValue = value;
for (int i = 0; i < getChildCount(); i++) {
@@ -67,7 +67,7 @@ public class SegmentedButtons extends LinearLayout {
c.setSelected(selected);
c.setTypeface(selected ? MEDIUM : REGULAR);
}
- fireOnSelected();
+ fireOnSelected(fromClick);
}
public void addButton(int labelResId, int contentDescriptionResId, Object value) {
@@ -100,9 +100,9 @@ public class SegmentedButtons extends LinearLayout {
}
}
- private void fireOnSelected() {
+ private void fireOnSelected(boolean fromClick) {
if (mCallback != null) {
- mCallback.onSelected(mSelectedValue);
+ mCallback.onSelected(mSelectedValue, fromClick);
}
}
@@ -115,11 +115,11 @@ public class SegmentedButtons extends LinearLayout {
private final View.OnClickListener mClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
- setSelectedValue(v.getTag());
+ setSelectedValue(v.getTag(), true /* fromClick */);
}
};
public interface Callback extends Interaction.Callback {
- void onSelected(Object value);
+ void onSelected(Object value, boolean fromClick);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index 0ab0392..3964820 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -741,12 +741,7 @@ public class VolumeDialog {
private void updateVolumeRowSliderTintH(VolumeRow row, boolean isActive) {
if (isActive && mExpanded) {
- row.slider.setFocusable(true);
- row.slider.setFocusableInTouchMode(true);
row.slider.requestFocus();
- } else {
- row.slider.setFocusableInTouchMode(false);
- row.slider.setFocusable(false);
}
final ColorStateList tint = isActive && row.slider.isEnabled() ? mActiveSliderTint
: mInactiveSliderTint;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
index 9a59a2a..32d6805 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
@@ -768,6 +768,7 @@ public class VolumeDialogController {
filter.addAction(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED);
filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
filter.addAction(Intent.ACTION_SCREEN_OFF);
+ filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
mContext.registerReceiver(this, filter, null, mWorker);
}
@@ -822,6 +823,9 @@ public class VolumeDialogController {
} else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
if (D.BUG) Log.d(TAG, "onReceive ACTION_SCREEN_OFF");
mCallbacks.onScreenOff();
+ } else if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
+ if (D.BUG) Log.d(TAG, "onReceive ACTION_CLOSE_SYSTEM_DIALOGS");
+ dismiss();
}
if (changed) {
mCallbacks.onStateChanged(mState);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
index fdf1840..4bb1011 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
@@ -126,6 +126,11 @@ public class VolumeDialogMotion {
return mChevron.getHeight() / 6;
}
+ private int chevronPosY() {
+ final Object tag = mChevron == null ? null : mChevron.getTag();
+ return tag == null ? 0 : (Integer) tag;
+ }
+
private void startShowAnimation() {
if (D.BUG) Log.d(TAG, "startShowAnimation");
mDialogView.animate()
@@ -139,7 +144,7 @@ public class VolumeDialogMotion {
if (mChevronPositionAnimator == null) return;
// reposition chevron
final float v = (Float) mChevronPositionAnimator.getAnimatedValue();
- final int posY = (Integer) mChevron.getTag();
+ final int posY = chevronPosY();
mChevron.setTranslationY(posY + v + -mDialogView.getTranslationY());
}})
.start();
@@ -198,9 +203,13 @@ public class VolumeDialogMotion {
setDismissing(true);
if (mShowing) {
mDialogView.animate().cancel();
- mContentsPositionAnimator.cancel();
+ if (mContentsPositionAnimator != null) {
+ mContentsPositionAnimator.cancel();
+ }
mContents.animate().cancel();
- mChevronPositionAnimator.cancel();
+ if (mChevronPositionAnimator != null) {
+ mChevronPositionAnimator.cancel();
+ }
mChevron.animate().cancel();
setShowing(false);
}
@@ -212,7 +221,7 @@ public class VolumeDialogMotion {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mContents.setTranslationY(-mDialogView.getTranslationY());
- int posY = (Integer) mChevron.getTag();
+ final int posY = chevronPosY();
mChevron.setTranslationY(posY + -mDialogView.getTranslationY());
}
})
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 8035cd3..3c9a7fc 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -391,7 +391,7 @@ public class ZenModePanel extends LinearLayout {
setExpanded(isShown());
mSessionZen = zen;
}
- mZenButtons.setSelectedValue(zen);
+ mZenButtons.setSelectedValue(zen, false /* fromClick */);
updateWidgets();
handleUpdateConditions();
if (mExpanded) {
@@ -968,10 +968,12 @@ public class ZenModePanel extends LinearLayout {
private final SegmentedButtons.Callback mZenButtonsCallback = new SegmentedButtons.Callback() {
@Override
- public void onSelected(final Object value) {
+ public void onSelected(final Object value, boolean fromClick) {
if (value != null && mZenButtons.isShown() && isAttachedToWindow()) {
final int zen = (Integer) value;
- MetricsLogger.action(mContext, MetricsLogger.QS_DND_ZEN_SELECT, zen);
+ if (fromClick) {
+ MetricsLogger.action(mContext, MetricsLogger.QS_DND_ZEN_SELECT, zen);
+ }
if (DEBUG) Log.d(mTag, "mZenButtonsCallback selected=" + zen);
final Uri realConditionId = getRealConditionId(mSessionExitCondition);
AsyncTask.execute(new Runnable() {
diff --git a/rs/java/android/renderscript/ScriptGroup.java b/rs/java/android/renderscript/ScriptGroup.java
index 9000d4d..54180f4 100644
--- a/rs/java/android/renderscript/ScriptGroup.java
+++ b/rs/java/android/renderscript/ScriptGroup.java
@@ -995,6 +995,8 @@ public final class ScriptGroup extends BaseObj {
*
* @param name name for the script group. Legal names can only contain letters, digits,
* '-', or '_'. The name can be no longer than 100 characters.
+ * Try to use unique names, to avoid name conflicts and reduce
+ * the cost of group creation.
* @param outputs futures intended as outputs of the script group
* @return a script group
*/
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
index aa72fba..06134e5 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
@@ -3277,11 +3277,11 @@ public final class ScriptIntrinsicBLAS extends ScriptIntrinsic {
* just before there's a shift down to drop the fractional parts. The output
* values are gated to 0 to 255 to fit in a byte, but the 10-bit format
* gives some headroom to avoid wrapping around on small overflows.
- *
+ *
* @param A The input allocation contains matrix A, supported elements type {@link Element#U8}.
- * @param a_offset The offset for all values in matrix A, e.g A[i,j] = A[i,j] - a_offset.
+ * @param a_offset The offset for all values in matrix A, e.g A[i,j] = A[i,j] - a_offset. Value should be from 0 to 255.
* @param B The input allocation contains matrix B, supported elements type {@link Element#U8}.
- * @param b_offset The offset for all values in matrix B, e.g B[i,j] = B[i,j] - b_offset.
+ * @param b_offset The offset for all values in matrix B, e.g B[i,j] = B[i,j] - b_offset. Value should be from 0 to 255.
* @param C The input allocation contains matrix C, supported elements type {@link Element#U8}.
* @param c_offset The offset for all values in matrix C.
* @param c_mult The multiplier for all values in matrix C, e.g C[i,j] = (C[i,j] + c_offset) * c_mult.
@@ -3289,6 +3289,12 @@ public final class ScriptIntrinsicBLAS extends ScriptIntrinsic {
public void BNNM(Allocation A, int a_offset, Allocation B, int b_offset, Allocation C, int c_offset, int c_mult) {
validateL3(Element.U8(mRS), NO_TRANSPOSE, TRANSPOSE, 0, A, B, C);
+ if (a_offset < 0 || a_offset > 255) {
+ throw new RSRuntimeException("Invalid a_offset passed to BNNM");
+ }
+ if (b_offset < 0 || b_offset > 255) {
+ throw new RSRuntimeException("Invalid b_offset passed to BNNM");
+ }
int M = -1, N = -1, K = -1;
M = A.getType().getY();
N = B.getType().getY();
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 1833a1c..ffc4fd8 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -696,8 +696,8 @@ nScriptIntrinsicBLAS_BNNM(JNIEnv *_env, jobject _this, jlong con, jlong id, jint
call.M = M;
call.N = N;
call.K = K;
- call.a_offset = a_offset;
- call.b_offset = b_offset;
+ call.a_offset = a_offset & 0xFF;
+ call.b_offset = b_offset & 0xFF;
call.c_offset = c_offset;
call.c_mult_int = c_mult_int;
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 7bcbcfb..57769e7 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -3351,6 +3351,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
case AccessibilityEvent.TYPE_TOUCH_INTERACTION_END:
case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER:
case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT:
+ // Also always dispatch the event that assist is reading context.
+ case AccessibilityEvent.TYPE_ASSIST_READING_CONTEXT:
// Also windows changing should always be anounced.
case AccessibilityEvent.TYPE_WINDOWS_CHANGED: {
return true;
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index af83a53..ed48f91 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -3223,6 +3223,27 @@ public class BackupManagerService {
}
}
+ void tearDownAgentAndKill(ApplicationInfo app) {
+ try {
+ // unbind and tidy up even on timeout or failure, just in case
+ mActivityManager.unbindBackupAgent(app);
+
+ // The agent was running with a stub Application object, so shut it down.
+ // !!! We hardcode the confirmation UI's package name here rather than use a
+ // manifest flag! TODO something less direct.
+ if (app.uid != Process.SYSTEM_UID
+ && !app.packageName.equals("com.android.backupconfirm")
+ && app.uid != Process.PHONE_UID) {
+ if (MORE_DEBUG) Slog.d(TAG, "Killing agent host process");
+ mActivityManager.killApplicationProcess(app.processName, app.uid);
+ } else {
+ if (MORE_DEBUG) Slog.d(TAG, "Not killing after operation: " + app.processName);
+ }
+ } catch (RemoteException e) {
+ Slog.d(TAG, "Lost app trying to shut down");
+ }
+ }
+
// Core logic for performing one package's full backup, gathering the tarball from the
// application and emitting it to the designated OutputStream.
@@ -3525,21 +3546,7 @@ public class BackupManagerService {
if (pkg != null) {
final ApplicationInfo app = pkg.applicationInfo;
if (app != null) {
- try {
- // unbind and tidy up even on timeout or failure, just in case
- mActivityManager.unbindBackupAgent(app);
-
- // The agent was running with a stub Application object, so shut it down.
- if (app.uid != Process.SYSTEM_UID
- && app.uid != Process.PHONE_UID) {
- if (MORE_DEBUG) Slog.d(TAG, "Backup complete, killing host process");
- mActivityManager.killApplicationProcess(app.processName, app.uid);
- } else {
- if (MORE_DEBUG) Slog.d(TAG, "Not killing after backup: " + app.processName);
- }
- } catch (RemoteException e) {
- Slog.d(TAG, "Lost app trying to shut down");
- }
+ tearDownAgentAndKill(app);
}
}
}
@@ -4697,7 +4704,11 @@ public class BackupManagerService {
mBytes = 0;
}
- public boolean restoreOneFile(InputStream instream) {
+ public IBackupAgent getAgent() {
+ return mAgent;
+ }
+
+ public boolean restoreOneFile(InputStream instream, boolean mustKillAgent) {
if (!isRunning()) {
Slog.w(TAG, "Restore engine used after halting");
return false;
@@ -5011,8 +5022,10 @@ public class BackupManagerService {
Slog.i(TAG, "No [more] data for this package; tearing down");
}
tearDownPipes();
- tearDownAgent(mTargetApp);
setRunning(false);
+ if (mustKillAgent) {
+ tearDownAgent(mTargetApp);
+ }
}
return (info != null);
}
@@ -5037,23 +5050,7 @@ public class BackupManagerService {
void tearDownAgent(ApplicationInfo app) {
if (mAgent != null) {
- try {
- // unbind and tidy up even on timeout or failure, just in case
- mActivityManager.unbindBackupAgent(app);
-
- // The agent was running with a stub Application object, so shut it down.
- // !!! We hardcode the confirmation UI's package name here rather than use a
- // manifest flag! TODO something less direct.
- if (app.uid != Process.SYSTEM_UID
- && !app.packageName.equals("com.android.backupconfirm")) {
- if (MORE_DEBUG) Slog.d(TAG, "Killing host process");
- mActivityManager.killApplicationProcess(app.processName, app.uid);
- } else {
- if (MORE_DEBUG) Slog.d(TAG, "Not killing after full restore");
- }
- } catch (RemoteException e) {
- Slog.d(TAG, "Lost app trying to shut down");
- }
+ tearDownAgentAndKill(app);
mAgent = null;
}
}
@@ -7956,7 +7953,7 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
IoUtils.closeQuietly(mTransportPipes[0]);
IoUtils.closeQuietly(mTransportPipes[1]);
- // Don't proceed until the engine has torn down the agent etc
+ // Don't proceed until the engine has finished
eThread.waitForResult();
if (MORE_DEBUG) {
@@ -7969,8 +7966,12 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
// If we hit a transport-level error, we are done with everything;
// if we hit an agent error we just go back to running the queue.
if (status == BackupTransport.TRANSPORT_OK) {
- // Clean finish, so just carry on
- nextState = UnifiedRestoreState.RUNNING_QUEUE;
+ // Clean finish means we issue the restore-finished callback
+ nextState = UnifiedRestoreState.RESTORE_FINISHED;
+
+ // the engine bound the target's agent, so recover that binding
+ // to use for the callback.
+ mAgent = mEngine.getAgent();
} else {
// Something went wrong somewhere. Whether it was at the transport
// level is immaterial; we need to tell the transport to bail
@@ -8021,7 +8022,8 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
@Override
public void run() {
while (mEngine.isRunning()) {
- mEngine.restoreOneFile(mEngineStream);
+ // Tell it to be sure to leave the agent instance up after finishing
+ mEngine.restoreOneFile(mEngineStream, false);
}
}
}
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 839b87a..d58d372 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -1611,8 +1611,7 @@ class AlarmManagerService extends SystemService {
if (mAlarmBatches.size() > 0) {
final Batch firstWakeup = findFirstWakeupBatchLocked();
final Batch firstBatch = mAlarmBatches.get(0);
- // always update the kernel alarms, as a backstop against missed wakeups
- if (firstWakeup != null) {
+ if (firstWakeup != null && mNextWakeup != firstWakeup.start) {
mNextWakeup = firstWakeup.start;
setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start);
}
@@ -1625,8 +1624,7 @@ class AlarmManagerService extends SystemService {
nextNonWakeup = mNextNonWakeupDeliveryTime;
}
}
- // always update the kernel alarm, as a backstop against missed wakeups
- if (nextNonWakeup != 0) {
+ if (nextNonWakeup != 0 && mNextNonWakeup != nextNonWakeup) {
mNextNonWakeup = nextNonWakeup;
setLocked(ELAPSED_REALTIME, nextNonWakeup);
}
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 79c66b9..f0fc399 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -116,6 +116,8 @@ public class AppOpsService extends IAppOpsService.Stub {
public final static class Op {
public final int uid;
public final String packageName;
+ public int proxyUid = -1;
+ public String proxyPackageName;
public final int op;
public int mode;
public int duration;
@@ -289,7 +291,8 @@ public class AppOpsService extends IAppOpsService.Stub {
for (int j=0; j<pkgOps.size(); j++) {
Op curOp = pkgOps.valueAt(j);
resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time,
- curOp.rejectTime, curOp.duration));
+ curOp.rejectTime, curOp.duration, curOp.proxyUid,
+ curOp.proxyPackageName));
}
} else {
for (int j=0; j<ops.length; j++) {
@@ -299,7 +302,8 @@ public class AppOpsService extends IAppOpsService.Stub {
resOps = new ArrayList<AppOpsManager.OpEntry>();
}
resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time,
- curOp.rejectTime, curOp.duration));
+ curOp.rejectTime, curOp.duration, curOp.proxyUid,
+ curOp.proxyPackageName));
}
}
}
@@ -659,9 +663,28 @@ public class AppOpsService extends IAppOpsService.Stub {
}
@Override
+ public int noteProxyOperation(int code, String proxyPackageName,
+ int proxiedUid, String proxiedPackageName) {
+ verifyIncomingOp(code);
+ final int proxyMode = noteOperationUnchecked(code, Binder.getCallingUid(),
+ proxyPackageName, -1, null);
+ if (proxyMode != AppOpsManager.MODE_ALLOWED || Binder.getCallingUid() == proxiedUid) {
+ return proxyMode;
+ }
+ return noteOperationUnchecked(code, proxiedUid, proxiedPackageName,
+ Binder.getCallingUid(), proxyPackageName);
+
+ }
+
+ @Override
public int noteOperation(int code, int uid, String packageName) {
verifyIncomingUid(uid);
verifyIncomingOp(code);
+ return noteOperationUnchecked(code, uid, packageName, 0, null);
+ }
+
+ private int noteOperationUnchecked(int code, int uid, String packageName,
+ int proxyUid, String proxyPackageName) {
synchronized (this) {
Ops ops = getOpsLocked(uid, packageName, true);
if (ops == null) {
@@ -690,6 +713,8 @@ public class AppOpsService extends IAppOpsService.Stub {
+ " package " + packageName);
op.time = System.currentTimeMillis();
op.rejectTime = 0;
+ op.proxyUid = proxyUid;
+ op.proxyPackageName = proxyPackageName;
return AppOpsManager.MODE_ALLOWED;
}
}
@@ -1051,6 +1076,14 @@ public class AppOpsService extends IAppOpsService.Stub {
if (dur != null) {
op.duration = Integer.parseInt(dur);
}
+ String proxyUid = parser.getAttributeValue(null, "pu");
+ if (proxyUid != null) {
+ op.proxyUid = Integer.parseInt(proxyUid);
+ }
+ String proxyPackageName = parser.getAttributeValue(null, "pp");
+ if (proxyPackageName != null) {
+ op.proxyPackageName = proxyPackageName;
+ }
HashMap<String, Ops> pkgOps = mUidOps.get(uid);
if (pkgOps == null) {
pkgOps = new HashMap<String, Ops>();
@@ -1132,6 +1165,14 @@ public class AppOpsService extends IAppOpsService.Stub {
if (dur != 0) {
out.attribute(null, "d", Integer.toString(dur));
}
+ int proxyUid = op.getProxyUid();
+ if (proxyUid != -1) {
+ out.attribute(null, "pu", Integer.toString(proxyUid));
+ }
+ String proxyPackageName = op.getProxyPackageName();
+ if (proxyPackageName != null) {
+ out.attribute(null, "pp", proxyPackageName);
+ }
out.endTag(null, "op");
}
out.endTag(null, "uid");
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 25f8872..b9f62e6 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -60,6 +60,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
+
class BluetoothManagerService extends IBluetoothManager.Stub {
private static final String TAG = "BluetoothManagerService";
private static final boolean DBG = false;
@@ -234,25 +235,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
sendEnableMsg(mQuietEnableExternal);
}
}
- } else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
- if (DBG) Log.d(TAG, "Bluetooth user switched");
- mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_USER_SWITCHED,
- intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0));
- } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
- if (DBG) Log.d(TAG, "Bluetooth boot completed");
- synchronized(mReceiver) {
- if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
- //Enable
- if (DBG) Log.d(TAG, "Auto-enabling Bluetooth.");
- sendEnableMsg(mQuietEnableExternal);
- }
- if (!isNameAndAddressSet()) {
- // Sync the Bluetooth name and address from the
- // Bluetooth Adapter
- if (DBG) Log.d(TAG, "Retrieving Bluetooth Adapter name and address...");
- getNameAndAddress();
- }
- }
}
}
};
@@ -277,9 +259,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
registerForBleScanModeChange();
mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
- IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
- filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
- filter.addAction(Intent.ACTION_USER_SWITCHED);
+ IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
registerForAirplaneMode(filter);
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
mContext.registerReceiver(mReceiver, filter);
@@ -790,6 +770,31 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
/**
+ * Send enable message and set adapter name and address. Called when the boot phase becomes
+ * PHASE_SYSTEM_SERVICES_READY.
+ */
+ public void handleOnBootPhase() {
+ if (DBG) Log.d(TAG, "Bluetooth boot completed");
+ if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
+ if (DBG) Log.d(TAG, "Auto-enabling Bluetooth.");
+ sendEnableMsg(mQuietEnableExternal);
+ }
+ if (!isNameAndAddressSet()) {
+ // Sync the Bluetooth name and address from the Bluetooth Adapter
+ if (DBG) Log.d(TAG, "Retrieving Bluetooth Adapter name and address...");
+ getNameAndAddress();
+ }
+ }
+
+ /**
+ * Called when switching to a different foreground user.
+ */
+ public void handleOnSwitchUser(int userHandle) {
+ if (DBG) Log.d(TAG, "Bluetooth user switched");
+ mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_USER_SWITCHED, userHandle, 0));
+ }
+
+ /**
* This class manages the clients connected to a given ProfileService
* and maintains the connection with that service.
*/
diff --git a/services/core/java/com/android/server/BluetoothService.java b/services/core/java/com/android/server/BluetoothService.java
new file mode 100644
index 0000000..73e8c52
--- /dev/null
+++ b/services/core/java/com/android/server/BluetoothService.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.Context;
+import android.util.Log;
+
+class BluetoothService extends SystemService {
+ private static final String TAG = "BluetoothService";
+ private BluetoothManagerService mBluetoothManagerService;
+
+ public BluetoothService(Context context) {
+ super(context);
+ mBluetoothManagerService = new BluetoothManagerService(context);
+ }
+
+ @Override
+ public void onStart() {
+ Log.d(TAG, "onStart: publishing BluetoothManagerService");
+ publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, mBluetoothManagerService);
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
+ Log.d(TAG, "onBootPhase: PHASE_SYSTEM_SERVICES_READY");
+ mBluetoothManagerService.handleOnBootPhase();
+ }
+ }
+
+ @Override
+ public void onSwitchUser(int userHandle) {
+ Log.d(TAG, "onSwitchUser: switching to user " + userHandle);
+ mBluetoothManagerService.handleOnSwitchUser(userHandle);
+ }
+}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2d5141e..7f124dc 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -93,6 +93,9 @@ import android.security.Credentials;
import android.security.KeyStore;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import android.util.LocalLog;
+import android.util.LocalLog.ReadOnlyLocalLog;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -137,13 +140,12 @@ import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Inet4Address;
-import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -415,6 +417,20 @@ public class ConnectivityService extends IConnectivityManager.Stub
// sequence number of NetworkRequests
private int mNextNetworkRequestId = 1;
+ // Array of <Network,ReadOnlyLocalLogs> tracking network validation and results
+ private static final int MAX_VALIDATION_LOGS = 10;
+ private final ArrayDeque<Pair<Network,ReadOnlyLocalLog>> mValidationLogs =
+ new ArrayDeque<Pair<Network,ReadOnlyLocalLog>>(MAX_VALIDATION_LOGS);
+
+ private void addValidationLogs(ReadOnlyLocalLog log, Network network) {
+ synchronized(mValidationLogs) {
+ while (mValidationLogs.size() >= MAX_VALIDATION_LOGS) {
+ mValidationLogs.removeLast();
+ }
+ mValidationLogs.addFirst(new Pair(network, log));
+ }
+ }
+
/**
* Implements support for the legacy "one network per network type" model.
*
@@ -1716,11 +1732,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
return ret;
}
- private boolean shouldPerformDiagnostics(String[] args) {
+ private boolean argsContain(String[] args, String target) {
for (String arg : args) {
- if (arg.equals("--diag")) {
- return true;
- }
+ if (arg.equals(target)) return true;
}
return false;
}
@@ -1738,7 +1752,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
final List<NetworkDiagnostics> netDiags = new ArrayList<NetworkDiagnostics>();
- if (shouldPerformDiagnostics(args)) {
+ if (argsContain(args, "--diag")) {
final long DIAG_TIME_MS = 5000;
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
// Start gathering diagnostic information.
@@ -1825,6 +1839,19 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
pw.decreaseIndent();
}
+
+ if (argsContain(args, "--short") == false) {
+ pw.println();
+ synchronized (mValidationLogs) {
+ pw.println("mValidationLogs (most recent first):");
+ for (Pair<Network,ReadOnlyLocalLog> p : mValidationLogs) {
+ pw.println(p.first);
+ pw.increaseIndent();
+ p.second.dump(fd, pw, args);
+ pw.decreaseIndent();
+ }
+ }
+ }
}
private boolean isLiveNetworkAgent(NetworkAgentInfo nai, String msg) {
@@ -2684,7 +2711,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
} else {
nai = getNetworkAgentInfoForNetwork(network);
}
- if (nai == null) return;
+ if (nai == null || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTING ||
+ nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) {
+ return;
+ }
// Revalidate if the app report does not match our current validated state.
if (hasConnectivity == nai.lastValidated) return;
final int uid = Binder.getCallingUid();
@@ -3841,6 +3871,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
synchronized (this) {
nai.networkMonitor.systemReady = mSystemReady;
}
+ addValidationLogs(nai.networkMonitor.getValidationLogs(), nai.network);
if (DBG) log("registerNetworkAgent " + nai);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai));
return nai.network.netId;
@@ -3984,51 +4015,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty();
}
- // TODO: investigate moving this into LinkProperties, if only to make more accurate
- // the isProvisioned() checks.
- private static Collection<InetAddress> getLikelyReachableDnsServers(LinkProperties lp) {
- final ArrayList<InetAddress> dnsServers = new ArrayList<InetAddress>();
- final List<RouteInfo> allRoutes = lp.getAllRoutes();
- for (InetAddress nameserver : lp.getDnsServers()) {
- // If the LinkProperties doesn't include a route to the nameserver, ignore it.
- final RouteInfo bestRoute = RouteInfo.selectBestRoute(allRoutes, nameserver);
- if (bestRoute == null) {
- continue;
- }
-
- // TODO: better source address evaluation for destination addresses.
- if (nameserver instanceof Inet4Address) {
- if (!lp.hasIPv4Address()) {
- continue;
- }
- } else if (nameserver instanceof Inet6Address) {
- if (nameserver.isLinkLocalAddress()) {
- if (((Inet6Address)nameserver).getScopeId() == 0) {
- // For now, just make sure link-local DNS servers have
- // scopedIds set, since DNS lookups will fail otherwise.
- // TODO: verify the scopeId matches that of lp's interface.
- continue;
- }
- } else {
- if (bestRoute.isIPv6Default() && !lp.hasGlobalIPv6Address()) {
- // TODO: reconsider all corner cases (disconnected ULA networks, ...).
- continue;
- }
- }
- }
-
- dnsServers.add(nameserver);
- }
- return Collections.unmodifiableList(dnsServers);
- }
-
private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId,
boolean flush, boolean useDefaultDns) {
- // TODO: consider comparing the getLikelyReachableDnsServers() lists, in case the
- // route to a DNS server has been removed (only really applicable in special cases
- // where there is no default route).
if (oldLp == null || (newLp.isIdenticalDnses(oldLp) == false)) {
- Collection<InetAddress> dnses = getLikelyReachableDnsServers(newLp);
+ Collection<InetAddress> dnses = newLp.getDnsServers();
if (dnses.size() == 0 && mDefaultDns != null && useDefaultDns) {
dnses = new ArrayList();
dnses.add(mDefaultDns);
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index dc203ff..c8dc565 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -158,15 +158,20 @@ public class DeviceIdleController extends SystemService
private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>();
/**
+ * App IDs of built-in system apps that have been white-listed.
+ */
+ private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray();
+
+ /**
* App IDs that have been white-listed to opt out of power save restrictions.
*/
- private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray();
+ private final SparseBooleanArray mPowerSaveWhitelistAllAppIds = new SparseBooleanArray();
/**
* Current app IDs that are in the complete power save white list. This array can
* be shared with others because it will not be modified once set.
*/
- private int[] mPowerSaveWhitelistAppIdArray = new int[0];
+ private int[] mPowerSaveWhitelistAllAppIdArray = new int[0];
/**
* List of end times for UIDs that are temporarily marked as being allowed to access
@@ -478,6 +483,7 @@ public class DeviceIdleController extends SystemService
handleWriteConfigFile();
} break;
case MSG_REPORT_IDLE_ON: {
+ EventLogTags.writeDeviceIdleOnStart();
mLocalPowerManager.setDeviceIdleMode(true);
try {
mNetworkPolicyManager.setDeviceIdleMode(true);
@@ -485,8 +491,10 @@ public class DeviceIdleController extends SystemService
} catch (RemoteException e) {
}
getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
+ EventLogTags.writeDeviceIdleOnComplete();
} break;
case MSG_REPORT_IDLE_OFF: {
+ EventLogTags.writeDeviceIdleOffStart("unknown");
mLocalPowerManager.setDeviceIdleMode(false);
try {
mNetworkPolicyManager.setDeviceIdleMode(false);
@@ -494,11 +502,14 @@ public class DeviceIdleController extends SystemService
} catch (RemoteException e) {
}
getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
+ EventLogTags.writeDeviceIdleOffComplete();
} break;
case MSG_REPORT_ACTIVE: {
String activeReason = (String)msg.obj;
int activeUid = msg.arg1;
boolean needBroadcast = msg.arg2 != 0;
+ EventLogTags.writeDeviceIdleOffStart(
+ activeReason != null ? activeReason : "unknown");
mLocalPowerManager.setDeviceIdleMode(false);
try {
mNetworkPolicyManager.setDeviceIdleMode(false);
@@ -508,6 +519,7 @@ public class DeviceIdleController extends SystemService
if (needBroadcast) {
getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
}
+ EventLogTags.writeDeviceIdleOffComplete();
} break;
case MSG_TEMP_APP_WHITELIST_TIMEOUT: {
int uid = msg.arg1;
@@ -557,17 +569,18 @@ public class DeviceIdleController extends SystemService
getContext().enforceCallingPermission(
Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
"No permission to change device idle whitelist");
+ final int callingUid = Binder.getCallingUid();
userId = ActivityManagerNative.getDefault().handleIncomingUser(
Binder.getCallingPid(),
- Binder.getCallingUid(),
+ callingUid,
userId,
/*allowAll=*/ false,
/*requireFull=*/ false,
"addPowerSaveTempWhitelistApp", null);
final long token = Binder.clearCallingIdentity();
try {
- DeviceIdleController.this.addPowerSaveTempWhitelistAppInternal(packageName,
- duration, userId);
+ DeviceIdleController.this.addPowerSaveTempWhitelistAppInternal(callingUid,
+ packageName, duration, userId);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -586,7 +599,7 @@ public class DeviceIdleController extends SystemService
public final class LocalService {
public void addPowerSaveTempWhitelistAppDirect(int appId, long duration) {
- DeviceIdleController.this.addPowerSaveTempWhitelistAppDirectInternal(appId, duration);
+ addPowerSaveTempWhitelistAppDirectInternal(0, appId, duration);
}
}
@@ -614,8 +627,9 @@ public class DeviceIdleController extends SystemService
try {
ApplicationInfo ai = pm.getApplicationInfo(pkg, 0);
if ((ai.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
- mPowerSaveWhitelistApps.put(ai.packageName,
- UserHandle.getAppId(ai.uid));
+ int appid = UserHandle.getAppId(ai.uid);
+ mPowerSaveWhitelistApps.put(ai.packageName, appid);
+ mPowerSaveWhitelistSystemAppIds.put(appid, true);
}
} catch (PackageManager.NameNotFoundException e) {
}
@@ -667,14 +681,15 @@ public class DeviceIdleController extends SystemService
mSensingAlarmIntent = PendingIntent.getBroadcast(getContext(), 0, intentSensing, 0);
mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
- mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
+ | Intent.FLAG_RECEIVER_FOREGROUND);
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(ACTION_STEP_IDLE_STATE);
getContext().registerReceiver(mReceiver, filter);
- mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAppIdArray);
+ mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
mDisplayManager.registerDisplayListener(mDisplayListener, null);
updateDisplayLocked();
@@ -747,7 +762,7 @@ public class DeviceIdleController extends SystemService
public int[] getAppIdWhitelistInternal() {
synchronized (this) {
- return mPowerSaveWhitelistAppIdArray;
+ return mPowerSaveWhitelistAllAppIdArray;
}
}
@@ -761,12 +776,12 @@ public class DeviceIdleController extends SystemService
* Adds an app to the temporary whitelist and resets the endTime for granting the
* app an exemption to access network and acquire wakelocks.
*/
- public void addPowerSaveTempWhitelistAppInternal(String packageName, long duration,
- int userId) {
+ public void addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName,
+ long duration, int userId) {
try {
int uid = getContext().getPackageManager().getPackageUid(packageName, userId);
int appId = UserHandle.getAppId(uid);
- addPowerSaveTempWhitelistAppDirectInternal(appId, duration);
+ addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration);
} catch (NameNotFoundException e) {
}
}
@@ -775,9 +790,17 @@ public class DeviceIdleController extends SystemService
* Adds an app to the temporary whitelist and resets the endTime for granting the
* app an exemption to access network and acquire wakelocks.
*/
- public void addPowerSaveTempWhitelistAppDirectInternal(int appId, long duration) {
+ public void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId,
+ long duration) {
final long timeNow = SystemClock.elapsedRealtime();
synchronized (this) {
+ int callingAppId = UserHandle.getAppId(callingUid);
+ if (callingAppId >= Process.FIRST_APPLICATION_UID) {
+ if (!mPowerSaveWhitelistSystemAppIds.get(callingAppId)) {
+ throw new SecurityException("Calling app " + UserHandle.formatUid(callingUid)
+ + " is not on whitelist");
+ }
+ }
duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION);
long currentEndTime = mTempWhitelistAppIdEndTimes.get(appId);
// Set the new end time
@@ -1026,25 +1049,25 @@ public class DeviceIdleController extends SystemService
}
private void updateWhitelistAppIdsLocked() {
- mPowerSaveWhitelistAppIds.clear();
+ mPowerSaveWhitelistAllAppIds.clear();
for (int i=0; i<mPowerSaveWhitelistApps.size(); i++) {
- mPowerSaveWhitelistAppIds.put(mPowerSaveWhitelistApps.valueAt(i), true);
+ mPowerSaveWhitelistAllAppIds.put(mPowerSaveWhitelistApps.valueAt(i), true);
}
for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) {
- mPowerSaveWhitelistAppIds.put(mPowerSaveWhitelistUserApps.valueAt(i), true);
+ mPowerSaveWhitelistAllAppIds.put(mPowerSaveWhitelistUserApps.valueAt(i), true);
}
- int size = mPowerSaveWhitelistAppIds.size();
+ int size = mPowerSaveWhitelistAllAppIds.size();
int[] appids = new int[size];
for (int i = 0; i < size; i++) {
- appids[i] = mPowerSaveWhitelistAppIds.keyAt(i);
+ appids[i] = mPowerSaveWhitelistAllAppIds.keyAt(i);
}
- mPowerSaveWhitelistAppIdArray = appids;
+ mPowerSaveWhitelistAllAppIdArray = appids;
if (mLocalPowerManager != null) {
if (DEBUG) {
Slog.d(TAG, "Setting wakelock whitelist to "
- + Arrays.toString(mPowerSaveWhitelistAppIdArray));
+ + Arrays.toString(mPowerSaveWhitelistAllAppIdArray));
}
- mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAppIdArray);
+ mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
}
}
@@ -1245,25 +1268,40 @@ public class DeviceIdleController extends SystemService
// Ignore, we always dump all.
} else if ("step".equals(arg)) {
synchronized (this) {
- stepIdleStateLocked();
- pw.print("Stepped to: "); pw.println(stateToString(mState));
+ long token = Binder.clearCallingIdentity();
+ try {
+ stepIdleStateLocked();
+ pw.print("Stepped to: "); pw.println(stateToString(mState));
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
return;
} else if ("disable".equals(arg)) {
synchronized (this) {
- if (mEnabled) {
- mEnabled = false;
- becomeActiveLocked("disabled", Process.myUid());
- pw.println("Idle mode disabled");
+ long token = Binder.clearCallingIdentity();
+ try {
+ if (mEnabled) {
+ mEnabled = false;
+ becomeActiveLocked("disabled", Process.myUid());
+ pw.println("Idle mode disabled");
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
return;
} else if ("enable".equals(arg)) {
synchronized (this) {
- if (!mEnabled) {
- mEnabled = true;
- becomeInactiveIfAppropriateLocked();
- pw.println("Idle mode enabled");
+ long token = Binder.clearCallingIdentity();
+ try {
+ if (!mEnabled) {
+ mEnabled = true;
+ becomeInactiveIfAppropriateLocked();
+ pw.println("Idle mode enabled");
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
return;
@@ -1273,40 +1311,50 @@ public class DeviceIdleController extends SystemService
}
return;
} else if ("whitelist".equals(arg)) {
- i++;
- while (i < args.length) {
- arg = args[i];
+ long token = Binder.clearCallingIdentity();
+ try {
i++;
- if (arg.length() < 1 || (arg.charAt(0) != '-'
- && arg.charAt(0) != '+')) {
- pw.println("Package must be prefixed with + or -: " + arg);
- return;
- }
- char op = arg.charAt(0);
- String pkg = arg.substring(1);
- if (op == '+') {
- if (addPowerSaveWhitelistAppInternal(pkg)) {
- pw.println("Added: " + pkg);
- } else {
- pw.println("Unknown package: " + pkg);
+ while (i < args.length) {
+ arg = args[i];
+ i++;
+ if (arg.length() < 1 || (arg.charAt(0) != '-'
+ && arg.charAt(0) != '+')) {
+ pw.println("Package must be prefixed with + or -: " + arg);
+ return;
}
- } else {
- if (removePowerSaveWhitelistAppInternal(pkg)) {
- pw.println("Removed: " + pkg);
+ char op = arg.charAt(0);
+ String pkg = arg.substring(1);
+ if (op == '+') {
+ if (addPowerSaveWhitelistAppInternal(pkg)) {
+ pw.println("Added: " + pkg);
+ } else {
+ pw.println("Unknown package: " + pkg);
+ }
+ } else {
+ if (removePowerSaveWhitelistAppInternal(pkg)) {
+ pw.println("Removed: " + pkg);
+ }
}
}
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
return;
} else if ("tempwhitelist".equals(arg)) {
- i++;
- if (i >= args.length) {
- pw.println("At least one package name must be specified");
- return;
- }
- while (i < args.length) {
- arg = args[i];
+ long token = Binder.clearCallingIdentity();
+ try {
i++;
- addPowerSaveTempWhitelistAppInternal(arg, 10000L, userId);
+ if (i >= args.length) {
+ pw.println("At least one package name must be specified");
+ return;
+ }
+ while (i < args.length) {
+ arg = args[i];
+ i++;
+ addPowerSaveTempWhitelistAppInternal(0, arg, 10000L, userId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
} else if (arg.length() > 0 && arg.charAt(0) == '-'){
pw.println("Unknown option: " + arg);
@@ -1337,12 +1385,12 @@ public class DeviceIdleController extends SystemService
pw.println(mPowerSaveWhitelistUserApps.keyAt(i));
}
}
- size = mPowerSaveWhitelistAppIds.size();
+ size = mPowerSaveWhitelistAllAppIds.size();
if (size > 0) {
- pw.println(" Whitelist app ids:");
+ pw.println(" Whitelist all app ids:");
for (int i = 0; i < size; i++) {
pw.print(" ");
- pw.print(mPowerSaveWhitelistAppIds.keyAt(i));
+ pw.print(mPowerSaveWhitelistAllAppIds.keyAt(i));
pw.println();
}
}
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 43b640b..7aebc1a 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -60,7 +60,7 @@ option java_package com.android.server
2752 notification_cancel_all (uid|1|5),(pid|1|5),(pkg|3),(userid|1|5),(required_flags|1),(forbidden_flags|1),(reason|1|5),(listener|3)
# when the notification panel is shown
# Note: New tag range starts here since 2753+ have been used below.
-27500 notification_panel_revealed
+27500 notification_panel_revealed (items|1)
# when the notification panel is hidden
27501 notification_panel_hidden
# when notifications are newly displayed on screen, or disappear from screen
@@ -183,6 +183,12 @@ option java_package com.android.server
34000 device_idle (state|1|5), (reason|3)
34001 device_idle_step
34002 device_idle_wake_from_idle (is_idle|1|5), (reason|3)
+34003 device_idle_on_start
+34004 device_idle_on_phase (what|3)
+34005 device_idle_on_complete
+34006 device_idle_off_start (reason|3)
+34007 device_idle_off_phase (what|3)
+34008 device_idle_off_complete
# ---------------------------
# DisplayManagerService.java
@@ -224,8 +230,8 @@ option java_package com.android.server
# ---------------------------
# IdleMaintenanceService.java
# ---------------------------
-2753 idle_maintenance_window_start (time|2|3), (lastUserActivity|2|3), (batteryLevel|1|6), (batteryCharging|1|5)
-2754 idle_maintenance_window_finish (time|2|3), (lastUserActivity|2|3), (batteryLevel|1|6), (batteryCharging|1|5)
+51500 idle_maintenance_window_start (time|2|3), (lastUserActivity|2|3), (batteryLevel|1|6), (batteryCharging|1|5)
+51501 idle_maintenance_window_finish (time|2|3), (lastUserActivity|2|3), (batteryLevel|1|6), (batteryCharging|1|5)
# ---------------------------
# MountService.java
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index ebbd9e5..42794e7 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -79,6 +79,7 @@ public class LockSettingsService extends ILockSettings.Stub {
void setCredential(String credential, String savedCredential, int userId)
throws RemoteException;
byte[] toHash(String credential, int userId);
+ String adjustForKeystore(String credential);
}
public LockSettingsService(Context context) {
@@ -528,6 +529,11 @@ public class LockSettingsService extends ILockSettings.Stub {
return LockPatternUtils.patternToHash(
LockPatternUtils.stringToPattern(pattern));
}
+
+ @Override
+ public String adjustForKeystore(String pattern) {
+ return LockPatternUtils.patternStringToBaseZero(pattern);
+ }
}
);
@@ -568,6 +574,11 @@ public class LockSettingsService extends ILockSettings.Stub {
public byte[] toHash(String password, int userId) {
return mLockPatternUtils.passwordToHash(password, userId);
}
+
+ @Override
+ public String adjustForKeystore(String password) {
+ return password;
+ }
}
);
}
@@ -587,7 +598,7 @@ public class LockSettingsService extends ILockSettings.Stub {
if (storedHash.version == CredentialHash.VERSION_LEGACY) {
byte[] hash = credentialUtil.toHash(credential, userId);
if (Arrays.equals(hash, storedHash.hash)) {
- unlockKeystore(credential, userId);
+ unlockKeystore(credentialUtil.adjustForKeystore(credential), userId);
// migrate credential to GateKeeper
credentialUtil.setCredential(credential, null, userId);
if (!hasChallenge) {
diff --git a/services/core/java/com/android/server/MasterClearReceiver.java b/services/core/java/com/android/server/MasterClearReceiver.java
index f1d5aa3..1653db9 100644
--- a/services/core/java/com/android/server/MasterClearReceiver.java
+++ b/services/core/java/com/android/server/MasterClearReceiver.java
@@ -16,12 +16,18 @@
package com.android.server;
+import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.os.AsyncTask;
import android.os.RecoverySystem;
+import android.os.storage.StorageManager;
import android.util.Log;
import android.util.Slog;
+import android.view.WindowManager;
+
+import com.android.internal.R;
import java.io.IOException;
@@ -39,6 +45,8 @@ public class MasterClearReceiver extends BroadcastReceiver {
final boolean shutdown = intent.getBooleanExtra("shutdown", false);
final String reason = intent.getStringExtra(Intent.EXTRA_REASON);
+ final boolean wipeExternalStorage = intent.getBooleanExtra(
+ Intent.EXTRA_WIPE_EXTERNAL_STORAGE, false);
Slog.w(TAG, "!!! FACTORY RESET !!!");
// The reboot call is blocking, so we need to do it on another thread.
@@ -55,6 +63,48 @@ public class MasterClearReceiver extends BroadcastReceiver {
}
}
};
- thr.start();
+
+ if (wipeExternalStorage) {
+ // thr will be started at the end of this task.
+ new WipeAdoptableDisksTask(context, thr).execute();
+ } else {
+ thr.start();
+ }
+ }
+
+ private class WipeAdoptableDisksTask extends AsyncTask<Void, Void, Void> {
+ private final Thread mChainedTask;
+ private final Context mContext;
+ private final ProgressDialog mProgressDialog;
+
+ public WipeAdoptableDisksTask(Context context, Thread chainedTask) {
+ mContext = context;
+ mChainedTask = chainedTask;
+ mProgressDialog = new ProgressDialog(context);
+ }
+
+ @Override
+ protected void onPreExecute() {
+ mProgressDialog.setIndeterminate(true);
+ mProgressDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+ mProgressDialog.setMessage(mContext.getText(R.string.progress_erasing));
+ mProgressDialog.show();
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ Slog.w(TAG, "Wiping adoptable disks");
+ StorageManager sm = (StorageManager) mContext.getSystemService(
+ Context.STORAGE_SERVICE);
+ sm.wipeAdoptableDisks();
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void result) {
+ mProgressDialog.dismiss();
+ mChainedTask.start();
+ }
+
}
}
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 4fe8fb9..c82ba24 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -18,9 +18,11 @@ package com.android.server;
import static com.android.internal.util.XmlUtils.readBooleanAttribute;
import static com.android.internal.util.XmlUtils.readIntAttribute;
+import static com.android.internal.util.XmlUtils.readLongAttribute;
import static com.android.internal.util.XmlUtils.readStringAttribute;
import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
import static com.android.internal.util.XmlUtils.writeIntAttribute;
+import static com.android.internal.util.XmlUtils.writeLongAttribute;
import static com.android.internal.util.XmlUtils.writeStringAttribute;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
@@ -50,11 +52,12 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
+import android.os.Looper;
import android.os.Message;
+import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
@@ -69,12 +72,14 @@ import android.os.storage.StorageResultCode;
import android.os.storage.StorageVolume;
import android.os.storage.VolumeInfo;
import android.os.storage.VolumeRecord;
+import android.provider.Settings;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.AtomicFile;
import android.util.Log;
import android.util.Slog;
+import android.util.TimeUtils;
import android.util.Xml;
import libcore.io.IoUtils;
@@ -84,6 +89,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IMediaContainerService;
import com.android.internal.os.SomeArgs;
+import com.android.internal.os.Zygote;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
@@ -108,9 +114,7 @@ import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
-import java.text.SimpleDateFormat;
import java.util.ArrayList;
-import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -179,7 +183,9 @@ class MountService extends IMountService.Stub
private static final boolean WATCHDOG_ENABLE = false;
private static final String TAG = "MountService";
+
private static final String TAG_STORAGE_BENCHMARK = "storage_benchmark";
+ private static final String TAG_STORAGE_TRIM = "storage_trim";
private static final String VOLD_TAG = "VoldConnector";
private static final String CRYPTD_TAG = "CryptdConnector";
@@ -228,6 +234,7 @@ class MountService extends IMountService.Stub
public static final int DISK_SIZE_CHANGED = 641;
public static final int DISK_LABEL_CHANGED = 642;
public static final int DISK_SCANNED = 643;
+ public static final int DISK_SYS_PATH_CHANGED = 644;
public static final int DISK_DESTROYED = 649;
public static final int VOLUME_CREATED = 650;
@@ -241,11 +248,7 @@ class MountService extends IMountService.Stub
public static final int MOVE_STATUS = 660;
public static final int BENCHMARK_RESULT = 661;
-
- /*
- * 700 series - fstrim
- */
- public static final int FstrimCompleted = 700;
+ public static final int TRIM_RESULT = 662;
}
private static final int VERSION_INIT = 1;
@@ -262,6 +265,9 @@ class MountService extends IMountService.Stub
private static final String ATTR_PART_GUID = "partGuid";
private static final String ATTR_NICKNAME = "nickname";
private static final String ATTR_USER_FLAGS = "userFlags";
+ private static final String ATTR_CREATED_MILLIS = "createdMillis";
+ private static final String ATTR_LAST_TRIM_MILLIS = "lastTrimMillis";
+ private static final String ATTR_LAST_BENCH_MILLIS = "lastBenchMillis";
private final AtomicFile mSettingsFile;
@@ -318,7 +324,6 @@ class MountService extends IMountService.Stub
throw new IllegalArgumentException("No volume found for ID " + id);
}
- @Deprecated
private String findVolumeIdForPath(String path) {
synchronized (mLock) {
for (int i = 0; i < mVolumes.size(); i++) {
@@ -331,6 +336,31 @@ class MountService extends IMountService.Stub
throw new IllegalArgumentException("No volume found for path " + path);
}
+ private VolumeRecord findRecordForPath(String path) {
+ synchronized (mLock) {
+ for (int i = 0; i < mVolumes.size(); i++) {
+ final VolumeInfo vol = mVolumes.valueAt(i);
+ if (vol.path != null && path.startsWith(vol.path)) {
+ return mRecords.get(vol.fsUuid);
+ }
+ }
+ }
+ return null;
+ }
+
+ private String scrubPath(String path) {
+ if (path.startsWith(Environment.getDataDirectory().getAbsolutePath())) {
+ return "internal";
+ }
+ final VolumeRecord rec = findRecordForPath(path);
+ if (rec == null || rec.createdMillis == 0) {
+ return "unknown";
+ } else {
+ return "ext:" + (int) ((System.currentTimeMillis() - rec.createdMillis)
+ / DateUtils.WEEK_IN_MILLIS) + "w";
+ }
+ }
+
private VolumeInfo findStorageForUuid(String volumeUuid) {
final StorageManager storage = mContext.getSystemService(StorageManager.class);
if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
@@ -342,6 +372,24 @@ class MountService extends IMountService.Stub
}
}
+ private boolean shouldBenchmark() {
+ final long benchInterval = Settings.Global.getLong(mContext.getContentResolver(),
+ Settings.Global.STORAGE_BENCHMARK_INTERVAL, DateUtils.WEEK_IN_MILLIS);
+ synchronized (mLock) {
+ for (int i = 0; i < mVolumes.size(); i++) {
+ final VolumeInfo vol = mVolumes.valueAt(i);
+ final VolumeRecord rec = mRecords.get(vol.fsUuid);
+ if (vol.isMountedReadable() && rec != null) {
+ final long benchAge = System.currentTimeMillis() - rec.lastBenchMillis;
+ if (benchAge >= benchInterval) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
private CountDownLatch findOrCreateDiskScanLatch(String diskId) {
synchronized (mLock) {
CountDownLatch latch = mDiskScanLatches.get(diskId);
@@ -560,16 +608,17 @@ class MountService extends IMountService.Stub
Slog.e(TAG, "Unable to record last fstrim!");
}
+ final boolean shouldBenchmark = shouldBenchmark();
try {
// This method must be run on the main (handler) thread,
// so it is safe to directly call into vold.
- mConnector.execute("fstrim", "dotrim");
- EventLogTags.writeFstrimStart(SystemClock.elapsedRealtime());
+ mConnector.execute("fstrim", shouldBenchmark ? "dotrimbench" : "dotrim");
} catch (NativeDaemonConnectorException ndce) {
Slog.e(TAG, "Failed to run fstrim!");
}
// invoke the completion callback, if any
+ // TODO: fstrim is non-blocking, so remove this useless callback
Runnable callback = (Runnable) msg.obj;
if (callback != null) {
callback.run();
@@ -675,13 +724,15 @@ class MountService extends IMountService.Stub
}
private void handleSystemReady() {
- resetIfReadyAndConnected();
+ synchronized (mLock) {
+ resetIfReadyAndConnectedLocked();
+ }
// Start scheduling nominally-daily fstrim operations
MountServiceIdler.scheduleIdlePass(mContext);
}
- private void resetIfReadyAndConnected() {
+ private void resetIfReadyAndConnectedLocked() {
Slog.d(TAG, "Thinking about reset, mSystemReady=" + mSystemReady
+ ", mDaemonConnected=" + mDaemonConnected);
if (mSystemReady && mDaemonConnected) {
@@ -780,7 +831,9 @@ class MountService extends IMountService.Stub
}
private void handleDaemonConnected() {
- resetIfReadyAndConnected();
+ synchronized (mLock) {
+ resetIfReadyAndConnectedLocked();
+ }
/*
* Now that we've done our initialization, release
@@ -889,6 +942,14 @@ class MountService extends IMountService.Stub
}
break;
}
+ case VoldResponseCode.DISK_SYS_PATH_CHANGED: {
+ if (cooked.length != 3) break;
+ final DiskInfo disk = mDisks.get(cooked[1]);
+ if (disk != null) {
+ disk.sysPath = cooked[2];
+ }
+ break;
+ }
case VoldResponseCode.DISK_DESTROYED: {
if (cooked.length != 2) break;
final DiskInfo disk = mDisks.remove(cooked[1]);
@@ -977,17 +1038,46 @@ class MountService extends IMountService.Stub
onMoveStatusLocked(status);
break;
}
-
case VoldResponseCode.BENCHMARK_RESULT: {
+ if (cooked.length != 7) break;
+ final String path = cooked[1];
+ final String ident = cooked[2];
+ final long create = Long.parseLong(cooked[3]);
+ final long drop = Long.parseLong(cooked[4]);
+ final long run = Long.parseLong(cooked[5]);
+ final long destroy = Long.parseLong(cooked[6]);
+
final DropBoxManager dropBox = mContext.getSystemService(DropBoxManager.class);
- dropBox.addText(TAG_STORAGE_BENCHMARK, raw);
+ dropBox.addText(TAG_STORAGE_BENCHMARK, scrubPath(path)
+ + " " + ident + " " + create + " " + run + " " + destroy);
+
+ final VolumeRecord rec = findRecordForPath(path);
+ if (rec != null) {
+ rec.lastBenchMillis = System.currentTimeMillis();
+ writeSettingsLocked();
+ }
+
break;
}
+ case VoldResponseCode.TRIM_RESULT: {
+ if (cooked.length != 4) break;
+ final String path = cooked[1];
+ final long bytes = Long.parseLong(cooked[2]);
+ final long time = Long.parseLong(cooked[3]);
+
+ final DropBoxManager dropBox = mContext.getSystemService(DropBoxManager.class);
+ dropBox.addText(TAG_STORAGE_TRIM, scrubPath(path)
+ + " " + bytes + " " + time);
+
+ final VolumeRecord rec = findRecordForPath(path);
+ if (rec != null) {
+ rec.lastTrimMillis = System.currentTimeMillis();
+ writeSettingsLocked();
+ }
- case VoldResponseCode.FstrimCompleted: {
- EventLogTags.writeFstrimFinish(SystemClock.elapsedRealtime());
break;
}
+
default: {
Slog.d(TAG, "Unhandled vold event " + code);
}
@@ -1099,6 +1189,7 @@ class MountService extends IMountService.Stub
if (rec == null) {
rec = new VolumeRecord(vol.type, vol.fsUuid);
rec.partGuid = vol.partGuid;
+ rec.createdMillis = System.currentTimeMillis();
if (vol.type == VolumeInfo.TYPE_PRIVATE) {
rec.nickname = vol.disk.getDescription();
}
@@ -1195,6 +1286,21 @@ class MountService extends IMountService.Stub
}
}
+ private void enforceAdminUser() {
+ UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ final int callingUserId = UserHandle.getCallingUserId();
+ boolean isAdmin;
+ long token = Binder.clearCallingIdentity();
+ try {
+ isAdmin = um.getUserInfo(callingUserId).isAdmin();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ if (!isAdmin) {
+ throw new SecurityException("Only admin users can adopt sd cards");
+ }
+ }
+
/**
* Constructs a new MountService instance
*
@@ -1363,6 +1469,9 @@ class MountService extends IMountService.Stub
meta.partGuid = readStringAttribute(in, ATTR_PART_GUID);
meta.nickname = readStringAttribute(in, ATTR_NICKNAME);
meta.userFlags = readIntAttribute(in, ATTR_USER_FLAGS);
+ meta.createdMillis = readLongAttribute(in, ATTR_CREATED_MILLIS);
+ meta.lastTrimMillis = readLongAttribute(in, ATTR_LAST_TRIM_MILLIS);
+ meta.lastBenchMillis = readLongAttribute(in, ATTR_LAST_BENCH_MILLIS);
return meta;
}
@@ -1373,6 +1482,9 @@ class MountService extends IMountService.Stub
writeStringAttribute(out, ATTR_PART_GUID, rec.partGuid);
writeStringAttribute(out, ATTR_NICKNAME, rec.nickname);
writeIntAttribute(out, ATTR_USER_FLAGS, rec.userFlags);
+ writeLongAttribute(out, ATTR_CREATED_MILLIS, rec.createdMillis);
+ writeLongAttribute(out, ATTR_LAST_TRIM_MILLIS, rec.lastTrimMillis);
+ writeLongAttribute(out, ATTR_LAST_BENCH_MILLIS, rec.lastBenchMillis);
out.endTag(null, TAG_VOLUME);
}
@@ -1530,6 +1642,7 @@ class MountService extends IMountService.Stub
@Override
public void partitionPrivate(String diskId) {
enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
+ enforceAdminUser();
waitForReady();
final CountDownLatch latch = findOrCreateDiskScanLatch(diskId);
@@ -1544,6 +1657,7 @@ class MountService extends IMountService.Stub
@Override
public void partitionMixed(String diskId, int ratio) {
enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
+ enforceAdminUser();
waitForReady();
final CountDownLatch latch = findOrCreateDiskScanLatch(diskId);
@@ -1600,7 +1714,7 @@ class MountService extends IMountService.Stub
// reset vold so we bind into new volume into place.
if (Objects.equals(mPrimaryStorageUuid, fsUuid)) {
mPrimaryStorageUuid = getDefaultPrimaryStorageUuid();
- resetIfReadyAndConnected();
+ resetIfReadyAndConnectedLocked();
}
writeSettingsLocked();
@@ -1628,7 +1742,7 @@ class MountService extends IMountService.Stub
}
writeSettingsLocked();
- resetIfReadyAndConnected();
+ resetIfReadyAndConnectedLocked();
}
}
@@ -1641,6 +1755,30 @@ class MountService extends IMountService.Stub
}
@Override
+ public void remountUid(int uid) {
+ enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
+ waitForReady();
+
+ final int mountExternal = mPms.getMountExternalMode(uid);
+ final String mode;
+ if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
+ mode = "default";
+ } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
+ mode = "read";
+ } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
+ mode = "write";
+ } else {
+ mode = "none";
+ }
+
+ try {
+ mConnector.execute("volume", "remount_uid", uid, mode);
+ } catch (NativeDaemonConnectorException e) {
+ Slog.w(TAG, "Failed to remount UID " + uid + " as " + mode + ": " + e);
+ }
+ }
+
+ @Override
public void setDebugFlags(int flags, int mask) {
enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
waitForReady();
@@ -1651,7 +1789,7 @@ class MountService extends IMountService.Stub
}
writeSettingsLocked();
- resetIfReadyAndConnected();
+ resetIfReadyAndConnectedLocked();
}
}
@@ -1688,7 +1826,7 @@ class MountService extends IMountService.Stub
Slog.d(TAG, "Skipping move to/from primary physical");
onMoveStatusLocked(MOVE_STATUS_COPY_FINISHED);
onMoveStatusLocked(PackageManager.MOVE_SUCCEEDED);
- resetIfReadyAndConnected();
+ resetIfReadyAndConnectedLocked();
} else {
final VolumeInfo from = Preconditions.checkNotNull(
@@ -2022,7 +2160,7 @@ class MountService extends IMountService.Stub
@Override
public void finishMediaUpdate() {
- if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
throw new SecurityException("no permission to call finishMediaUpdate()");
}
if (mUnmountSignal != null) {
@@ -3184,11 +3322,9 @@ class MountService extends IMountService.Stub
mConnector.dump(fd, pw, args);
pw.decreaseIndent();
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-
pw.println();
pw.print("Last maintenance: ");
- pw.println(sdf.format(new Date(mLastMaintenance)));
+ pw.println(TimeUtils.formatForLogging(mLastMaintenance));
}
/** {@inheritDoc} */
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 5bce6eb..aace66c 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -18,6 +18,7 @@ package com.android.server;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
+import com.android.internal.inputmethod.InputMethodUtils;
import com.android.internal.textservice.ISpellCheckerService;
import com.android.internal.textservice.ISpellCheckerSession;
import com.android.internal.textservice.ISpellCheckerSessionListener;
@@ -61,9 +62,11 @@ import android.view.textservice.SpellCheckerSubtype;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -141,7 +144,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
buildSpellCheckerMapLocked(mContext, mSpellCheckerList, mSpellCheckerMap, mSettings);
SpellCheckerInfo sci = getCurrentSpellChecker(null);
if (sci == null) {
- sci = findAvailSpellCheckerLocked(null, null);
+ sci = findAvailSpellCheckerLocked(null);
if (sci != null) {
// Set the current spell checker if there is one or more spell checkers
// available. In this case, "sci" is the first one in the available spell
@@ -190,7 +193,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
change == PACKAGE_PERMANENT_CHANGE || change == PACKAGE_TEMPORARY_CHANGE
// Package modified
|| isPackageModified(packageName)) {
- sci = findAvailSpellCheckerLocked(null, packageName);
+ sci = findAvailSpellCheckerLocked(packageName);
if (sci != null) {
setCurrentSpellCheckerLocked(sci.getId());
}
@@ -331,8 +334,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
mSpellCheckerBindGroups.clear();
}
- // TODO: find an appropriate spell checker for specified locale
- private SpellCheckerInfo findAvailSpellCheckerLocked(String locale, String prefPackage) {
+ private SpellCheckerInfo findAvailSpellCheckerLocked(String prefPackage) {
final int spellCheckersCount = mSpellCheckerList.size();
if (spellCheckersCount == 0) {
Slog.w(TAG, "no available spell checker services found");
@@ -349,6 +351,38 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
}
}
}
+
+ // Look up a spell checker based on the system locale.
+ // TODO: Still there is a room to improve in the following logic: e.g., check if the package
+ // is pre-installed or not.
+ final Locale systemLocal = mContext.getResources().getConfiguration().locale;
+ final ArrayList<Locale> suitableLocales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(systemLocal);
+ if (DBG) {
+ Slog.w(TAG, "findAvailSpellCheckerLocked suitableLocales="
+ + Arrays.toString(suitableLocales.toArray(new Locale[suitableLocales.size()])));
+ }
+ final int localeCount = suitableLocales.size();
+ for (int localeIndex = 0; localeIndex < localeCount; ++localeIndex) {
+ final Locale locale = suitableLocales.get(localeIndex);
+ for (int spellCheckersIndex = 0; spellCheckersIndex < spellCheckersCount;
+ ++spellCheckersIndex) {
+ final SpellCheckerInfo info = mSpellCheckerList.get(spellCheckersIndex);
+ final int subtypeCount = info.getSubtypeCount();
+ for (int subtypeIndex = 0; subtypeIndex < subtypeCount; ++subtypeIndex) {
+ final SpellCheckerSubtype subtype = info.getSubtypeAt(subtypeIndex);
+ final Locale subtypeLocale = InputMethodUtils.constructLocaleFromString(
+ subtype.getLocale());
+ if (locale.equals(subtypeLocale)) {
+ // TODO: We may have more spell checkers that fall into this category.
+ // Ideally we should pick up the most suitable one instead of simply
+ // returning the first found one.
+ return info;
+ }
+ }
+ }
+ }
+
if (spellCheckersCount > 1) {
Slog.w(TAG, "more than one spell checker service found, picking first");
}
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 20f6f1c..30f4dce 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -47,7 +47,10 @@ import android.media.AudioAttributes;
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IBatteryStats;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
@@ -58,6 +61,8 @@ public class VibratorService extends IVibratorService.Stub
private static final boolean DEBUG = false;
private final LinkedList<Vibration> mVibrations;
+ private final LinkedList<VibrationInfo> mPreviousVibrations;
+ private final int mPreviousVibrationsLimit;
private Vibration mCurrentVibration;
private final WorkSource mTmpWorkSource = new WorkSource();
private final Handler mH = new Handler();
@@ -146,6 +151,47 @@ public class VibratorService extends IVibratorService.Stub
}
}
+ private static class VibrationInfo {
+ long timeout;
+ long startTime;
+ long[] pattern;
+ int repeat;
+ int usageHint;
+ int uid;
+ String opPkg;
+
+ public VibrationInfo(long timeout, long startTime, long[] pattern, int repeat,
+ int usageHint, int uid, String opPkg) {
+ this.timeout = timeout;
+ this.startTime = startTime;
+ this.pattern = pattern;
+ this.repeat = repeat;
+ this.usageHint = usageHint;
+ this.uid = uid;
+ this.opPkg = opPkg;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder()
+ .append("timeout: ")
+ .append(timeout)
+ .append(", startTime: ")
+ .append(startTime)
+ .append(", pattern: ")
+ .append(Arrays.toString(pattern))
+ .append(", repeat: ")
+ .append(repeat)
+ .append(", usageHint: ")
+ .append(usageHint)
+ .append(", uid: ")
+ .append(uid)
+ .append(", opPkg: ")
+ .append(opPkg)
+ .toString();
+ }
+ }
+
VibratorService(Context context) {
// Reset the hardware to a default state, in case this is a runtime
// restart instead of a fresh boot.
@@ -161,7 +207,11 @@ public class VibratorService extends IVibratorService.Stub
mBatteryStatsService = IBatteryStats.Stub.asInterface(ServiceManager.getService(
BatteryStats.SERVICE_NAME));
- mVibrations = new LinkedList<Vibration>();
+ mPreviousVibrationsLimit = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_previousVibrationsDumpLimit);
+
+ mVibrations = new LinkedList<>();
+ mPreviousVibrations = new LinkedList<>();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
@@ -252,6 +302,7 @@ public class VibratorService extends IVibratorService.Stub
removeVibrationLocked(token);
doCancelVibrateLocked();
mCurrentVibration = vib;
+ addToPreviousVibrationsLocked(vib);
startVibrationLocked(vib);
}
} finally {
@@ -315,6 +366,7 @@ public class VibratorService extends IVibratorService.Stub
mCurrentVibration = vib;
startVibrationLocked(vib);
}
+ addToPreviousVibrationsLocked(vib);
}
}
finally {
@@ -322,6 +374,14 @@ public class VibratorService extends IVibratorService.Stub
}
}
+ private void addToPreviousVibrationsLocked(Vibration vib) {
+ if (mPreviousVibrations.size() > mPreviousVibrationsLimit) {
+ mPreviousVibrations.removeFirst();
+ }
+ mPreviousVibrations.addLast(new VibratorService.VibrationInfo(vib.mTimeout, vib.mStartTime,
+ vib.mPattern, vib.mRepeat, vib.mUsageHint, vib.mUid, vib.mOpPkg));
+ }
+
@Override // Binder call
public void cancelVibrate(IBinder token) {
mContext.enforceCallingOrSelfPermission(
@@ -649,7 +709,6 @@ public class VibratorService extends IVibratorService.Stub
if (!mDone) {
// If this vibration finished naturally, start the next
// vibration.
- mVibrations.remove(mVibration);
unlinkVibration(mVibration);
startNextVibrationLocked();
}
@@ -685,4 +744,23 @@ public class VibratorService extends IVibratorService.Stub
}
}
};
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+
+ pw.println("Permission Denial: can't dump vibrator service from from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid());
+ return;
+ }
+ pw.println("Previous vibrations:");
+ synchronized (mVibrations) {
+ for (VibrationInfo info : mPreviousVibrations) {
+ pw.print(" ");
+ pw.println(info.toString());
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 50d311f..a270974 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -86,7 +86,6 @@ import com.google.android.collect.Sets;
import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
@@ -115,7 +114,6 @@ public class AccountManagerService
implements RegisteredServicesCacheListener<AuthenticatorDescription> {
private static final String TAG = "AccountManagerService";
- private static final int TIMEOUT_DELAY_MS = 1000 * 60;
private static final String DATABASE_NAME = "accounts.db";
private static final int DATABASE_VERSION = 8;
@@ -216,7 +214,7 @@ public class AccountManagerService
new HashMap<Account, HashMap<String, String>>();
/** protected by the {@link #cacheLock} */
- private final HashMap<Account, WeakReference<TokenCache>> accountTokenCaches = new HashMap<>();
+ private final TokenCache accountTokenCaches = new TokenCache();
/**
* protected by the {@link #cacheLock}
@@ -529,7 +527,7 @@ public class AccountManagerService
+ ", pid " + Binder.getCallingPid());
}
if (account == null) throw new IllegalArgumentException("account is null");
- if (!isAccountOwnedByCallingUid(account.type, callingUid)) {
+ if (!isAccountManagedByCaller(account.type, callingUid)) {
String msg = String.format(
"uid %s cannot get secrets for accounts of type: %s",
callingUid,
@@ -627,7 +625,7 @@ public class AccountManagerService
}
if (account == null) throw new IllegalArgumentException("account is null");
if (key == null) throw new IllegalArgumentException("key is null");
- if (!isAccountOwnedByCallingUid(account.type, callingUid)) {
+ if (!isAccountManagedByCaller(account.type, callingUid)) {
String msg = String.format(
"uid %s cannot get user data for accounts of type: %s",
callingUid,
@@ -645,15 +643,22 @@ public class AccountManagerService
@Override
public AuthenticatorDescription[] getAuthenticatorTypes(int userId) {
+ int callingUid = Binder.getCallingUid();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "getAuthenticatorTypes: "
+ "for user id " + userId
- + "caller's uid " + Binder.getCallingUid()
+ + "caller's uid " + callingUid
+ ", pid " + Binder.getCallingPid());
}
// Only allow the system process to read accounts of other users
- enforceCrossUserPermission(userId, "User " + UserHandle.getCallingUserId()
- + " trying get authenticator types for " + userId);
+ if (isCrossUser(callingUid, userId)) {
+ throw new SecurityException(
+ String.format(
+ "User %s tying to get authenticator types for %s" ,
+ UserHandle.getCallingUserId(),
+ userId));
+ }
+
final long identityToken = clearCallingIdentity();
try {
Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>>
@@ -672,14 +677,12 @@ public class AccountManagerService
}
}
- private void enforceCrossUserPermission(int userId, String errorMessage) {
- if (userId != UserHandle.getCallingUserId()
- && Binder.getCallingUid() != Process.myUid()
+ private boolean isCrossUser(int callingUid, int userId) {
+ return (userId != UserHandle.getCallingUserId()
+ && callingUid != Process.myUid()
&& mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException(errorMessage);
- }
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+ != PackageManager.PERMISSION_GRANTED);
}
@Override
@@ -691,7 +694,7 @@ public class AccountManagerService
+ ", pid " + Binder.getCallingPid());
}
if (account == null) throw new IllegalArgumentException("account is null");
- if (!isAccountOwnedByCallingUid(account.type, callingUid)) {
+ if (!isAccountManagedByCaller(account.type, callingUid)) {
String msg = String.format(
"uid %s cannot explicitly add accounts of type: %s",
callingUid,
@@ -720,8 +723,11 @@ public class AccountManagerService
@Override
public void copyAccountToUser(final IAccountManagerResponse response, final Account account,
int userFrom, int userTo) {
- enforceCrossUserPermission(UserHandle.USER_ALL, "Calling copyAccountToUser requires "
+ int callingUid = Binder.getCallingUid();
+ if (isCrossUser(callingUid, UserHandle.USER_ALL)) {
+ throw new SecurityException("Calling copyAccountToUser requires "
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+ }
final UserAccounts fromAccounts = getUserAccounts(userFrom);
final UserAccounts toAccounts = getUserAccounts(userTo);
if (fromAccounts == null || toAccounts == null) {
@@ -784,7 +790,7 @@ public class AccountManagerService
if (account == null) {
throw new IllegalArgumentException("account is null");
}
- if (!isAccountOwnedByCallingUid(account.type, callingUid)) {
+ if (!isAccountManagedByCaller(account.type, callingUid)) {
String msg = String.format(
"uid %s cannot notify authentication for accounts of type: %s",
callingUid,
@@ -957,17 +963,18 @@ public class AccountManagerService
@Override
public void hasFeatures(IAccountManagerResponse response,
Account account, String[] features) {
+ int callingUid = Binder.getCallingUid();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "hasFeatures: " + account
+ ", response " + response
+ ", features " + stringArrayToString(features)
- + ", caller's uid " + Binder.getCallingUid()
+ + ", caller's uid " + callingUid
+ ", pid " + Binder.getCallingPid());
}
if (response == null) throw new IllegalArgumentException("response is null");
if (account == null) throw new IllegalArgumentException("account is null");
if (features == null) throw new IllegalArgumentException("features is null");
- checkReadAccountsPermission();
+ checkReadAccountsPermitted(callingUid, account.type);
UserAccounts accounts = getUserAccountsForCaller();
long identityToken = clearCallingIdentity();
try {
@@ -1043,7 +1050,7 @@ public class AccountManagerService
+ ", pid " + Binder.getCallingPid());
}
if (accountToRename == null) throw new IllegalArgumentException("account is null");
- if (!isAccountOwnedByCallingUid(accountToRename.type, callingUid)) {
+ if (!isAccountManagedByCaller(accountToRename.type, callingUid)) {
String msg = String.format(
"uid %s cannot rename accounts of type: %s",
callingUid,
@@ -1053,8 +1060,7 @@ public class AccountManagerService
UserAccounts accounts = getUserAccountsForCaller();
long identityToken = clearCallingIdentity();
try {
- Account resultingAccount = renameAccountInternal(accounts, accountToRename, newName,
- callingUid);
+ Account resultingAccount = renameAccountInternal(accounts, accountToRename, newName);
Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, resultingAccount.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, resultingAccount.type);
@@ -1069,7 +1075,7 @@ public class AccountManagerService
}
private Account renameAccountInternal(
- UserAccounts accounts, Account accountToRename, String newName, int callingUid) {
+ UserAccounts accounts, Account accountToRename, String newName) {
Account resultAccount = null;
/*
* Cancel existing notifications. Let authenticators
@@ -1179,16 +1185,20 @@ public class AccountManagerService
}
if (response == null) throw new IllegalArgumentException("response is null");
if (account == null) throw new IllegalArgumentException("account is null");
-
// Only allow the system process to modify accounts of other users
- enforceCrossUserPermission(userId, "User " + UserHandle.getCallingUserId()
- + " trying to remove account for " + userId);
+ if (isCrossUser(callingUid, userId)) {
+ throw new SecurityException(
+ String.format(
+ "User %s tying remove account for %s" ,
+ UserHandle.getCallingUserId(),
+ userId));
+ }
/*
* Only the system or authenticator should be allowed to remove accounts for that
* authenticator. This will let users remove accounts (via Settings in the system) but not
* arbitrary applications (like competing authenticators).
*/
- if (!isAccountOwnedByCallingUid(account.type, callingUid) && !isSystemUid(callingUid)) {
+ if (!isAccountManagedByCaller(account.type, callingUid) && !isSystemUid(callingUid)) {
String msg = String.format(
"uid %s cannot remove accounts of type: %s",
callingUid,
@@ -1252,7 +1262,7 @@ public class AccountManagerService
*/
Log.e(TAG, "account is null");
return false;
- } else if (!isAccountOwnedByCallingUid(account.type, callingUid)) {
+ } else if (!isAccountManagedByCaller(account.type, callingUid)) {
String msg = String.format(
"uid %s cannot explicitly add accounts of type: %s",
callingUid,
@@ -1398,16 +1408,7 @@ public class AccountManagerService
return;
}
// Also wipe out cached token in memory.
- for (Account a : accounts.accountTokenCaches.keySet()) {
- if (a.type.equals(accountType)) {
- WeakReference<TokenCache> tokenCacheRef =
- accounts.accountTokenCaches.get(a);
- TokenCache cache = null;
- if (tokenCacheRef != null && (cache = tokenCacheRef.get()) != null) {
- cache.remove(authToken);
- }
- }
- }
+ accounts.accountTokenCaches.remove(accountType, authToken);
}
private void invalidateAuthTokenLocked(UserAccounts accounts, SQLiteDatabase db,
@@ -1459,11 +1460,8 @@ public class AccountManagerService
cancelNotification(getSigninRequiredNotificationId(accounts, account),
new UserHandle(accounts.userId));
synchronized (accounts.cacheLock) {
- TokenCache cache = getTokenCacheForAccountLocked(accounts, account);
- if (cache != null) {
- cache.put(token, tokenType, callerPkg, callerSigDigest, expiryMillis);
- }
- return;
+ accounts.accountTokenCaches.put(
+ account, token, tokenType, callerPkg, callerSigDigest, expiryMillis);
}
}
@@ -1512,7 +1510,7 @@ public class AccountManagerService
}
if (account == null) throw new IllegalArgumentException("account is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
- if (!isAccountOwnedByCallingUid(account.type, callingUid)) {
+ if (!isAccountManagedByCaller(account.type, callingUid)) {
String msg = String.format(
"uid %s cannot peek the authtokens associated with accounts of type: %s",
callingUid,
@@ -1539,7 +1537,7 @@ public class AccountManagerService
}
if (account == null) throw new IllegalArgumentException("account is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
- if (!isAccountOwnedByCallingUid(account.type, callingUid)) {
+ if (!isAccountManagedByCaller(account.type, callingUid)) {
String msg = String.format(
"uid %s cannot set auth tokens associated with accounts of type: %s",
callingUid,
@@ -1564,7 +1562,7 @@ public class AccountManagerService
+ ", pid " + Binder.getCallingPid());
}
if (account == null) throw new IllegalArgumentException("account is null");
- if (!isAccountOwnedByCallingUid(account.type, callingUid)) {
+ if (!isAccountManagedByCaller(account.type, callingUid)) {
String msg = String.format(
"uid %s cannot set secrets for accounts of type: %s",
callingUid,
@@ -1627,7 +1625,7 @@ public class AccountManagerService
+ ", pid " + Binder.getCallingPid());
}
if (account == null) throw new IllegalArgumentException("account is null");
- if (!isAccountOwnedByCallingUid(account.type, callingUid)) {
+ if (!isAccountManagedByCaller(account.type, callingUid)) {
String msg = String.format(
"uid %s cannot clear passwords for accounts of type: %s",
callingUid,
@@ -1654,7 +1652,7 @@ public class AccountManagerService
}
if (key == null) throw new IllegalArgumentException("key is null");
if (account == null) throw new IllegalArgumentException("account is null");
- if (!isAccountOwnedByCallingUid(account.type, callingUid)) {
+ if (!isAccountManagedByCaller(account.type, callingUid)) {
String msg = String.format(
"uid %s cannot set user data for accounts of type: %s",
callingUid,
@@ -1780,7 +1778,6 @@ public class AccountManagerService
final boolean notifyOnAuthFailure,
final boolean expectActivityLaunch,
final Bundle loginOptions) {
-
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "getAuthToken: " + account
+ ", response " + response
@@ -1877,6 +1874,9 @@ public class AccountManagerService
callerPkg,
callerPkgSigDigest);
if (token != null) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "getAuthToken: cache hit ofr custom token authenticator.");
+ }
Bundle result = new Bundle();
result.putString(AccountManager.KEY_AUTHTOKEN, token);
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
@@ -1914,10 +1914,11 @@ public class AccountManagerService
public void onResult(Bundle result) {
if (result != null) {
if (result.containsKey(AccountManager.KEY_AUTH_TOKEN_LABEL)) {
- Intent intent = newGrantCredentialsPermissionIntent(account, callerUid,
+ Intent intent = newGrantCredentialsPermissionIntent(
+ account,
+ callerUid,
new AccountAuthenticatorResponse(this),
- authTokenType,
- result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL));
+ authTokenType);
Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
onResult(bundle);
@@ -1995,9 +1996,6 @@ public class AccountManagerService
GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, -1);
String authTokenType = intent.getStringExtra(
GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE);
- String authTokenLabel = intent.getStringExtra(
- GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_LABEL);
-
final String titleAndSubtitle =
mContext.getString(R.string.permission_request_notification_with_subtitle,
account.name);
@@ -2025,7 +2023,7 @@ public class AccountManagerService
}
private Intent newGrantCredentialsPermissionIntent(Account account, int uid,
- AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) {
+ AccountAuthenticatorResponse response, String authTokenType) {
Intent intent = new Intent(mContext, GrantCredentialsPermissionActivity.class);
// See FLAG_ACTIVITY_NEW_TASK docs for limitations and benefits of the flag.
@@ -2149,6 +2147,7 @@ public class AccountManagerService
public void addAccountAsUser(final IAccountManagerResponse response, final String accountType,
final String authTokenType, final String[] requiredFeatures,
final boolean expectActivityLaunch, final Bundle optionsIn, int userId) {
+ int callingUid = Binder.getCallingUid();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "addAccount: accountType " + accountType
+ ", response " + response
@@ -2161,10 +2160,14 @@ public class AccountManagerService
}
if (response == null) throw new IllegalArgumentException("response is null");
if (accountType == null) throw new IllegalArgumentException("accountType is null");
-
// Only allow the system process to add accounts of other users
- enforceCrossUserPermission(userId, "User " + UserHandle.getCallingUserId()
- + " trying to add account for " + userId);
+ if (isCrossUser(callingUid, userId)) {
+ throw new SecurityException(
+ String.format(
+ "User %s trying to add account for %s" ,
+ UserHandle.getCallingUserId(),
+ userId));
+ }
// Is user disallowed from modifying accounts?
if (!canUserModifyAccounts(userId)) {
@@ -2235,20 +2238,28 @@ public class AccountManagerService
}
@Override
- public void confirmCredentialsAsUser(IAccountManagerResponse response,
- final Account account, final Bundle options, final boolean expectActivityLaunch,
+ public void confirmCredentialsAsUser(
+ IAccountManagerResponse response,
+ final Account account,
+ final Bundle options,
+ final boolean expectActivityLaunch,
int userId) {
- // Only allow the system process to read accounts of other users
- enforceCrossUserPermission(userId, "User " + UserHandle.getCallingUserId()
- + " trying to confirm account credentials for " + userId);
-
+ int callingUid = Binder.getCallingUid();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "confirmCredentials: " + account
+ ", response " + response
+ ", expectActivityLaunch " + expectActivityLaunch
- + ", caller's uid " + Binder.getCallingUid()
+ + ", caller's uid " + callingUid
+ ", pid " + Binder.getCallingPid());
}
+ // Only allow the system process to read accounts of other users
+ if (isCrossUser(callingUid, userId)) {
+ throw new SecurityException(
+ String.format(
+ "User %s trying to confirm account credentials for %s" ,
+ UserHandle.getCallingUserId(),
+ userId));
+ }
if (response == null) throw new IllegalArgumentException("response is null");
if (account == null) throw new IllegalArgumentException("account is null");
UserAccounts accounts = getUserAccounts(userId);
@@ -2324,7 +2335,7 @@ public class AccountManagerService
}
if (response == null) throw new IllegalArgumentException("response is null");
if (accountType == null) throw new IllegalArgumentException("accountType is null");
- if (!isAccountOwnedByCallingUid(accountType, callingUid) && !isSystemUid(callingUid)) {
+ if (!isAccountManagedByCaller(accountType, callingUid) && !isSystemUid(callingUid)) {
String msg = String.format(
"uid %s cannot edit authenticator properites for account type: %s",
callingUid,
@@ -2457,9 +2468,11 @@ public class AccountManagerService
* @hide
*/
public Account[] getAccounts(int userId) {
- checkReadAccountsPermission();
UserAccounts accounts = getUserAccounts(userId);
int callingUid = Binder.getCallingUid();
+ if (!isReadAccountsPermitted(callingUid, null)) {
+ return new Account[0];
+ }
long identityToken = clearCallingIdentity();
try {
synchronized (accounts.cacheLock) {
@@ -2519,7 +2532,10 @@ public class AccountManagerService
return getAccountsAsUser(type, userId, null, -1);
}
- private Account[] getAccountsAsUser(String type, int userId, String callingPackage,
+ private Account[] getAccountsAsUser(
+ String type,
+ int userId,
+ String callingPackage,
int packageUid) {
int callingUid = Binder.getCallingUid();
// Only allow the system process to read accounts of other users
@@ -2542,7 +2558,12 @@ public class AccountManagerService
if (packageUid != -1 && UserHandle.isSameApp(callingUid, Process.myUid())) {
callingUid = packageUid;
}
- checkReadAccountsPermission();
+
+ // Authenticators should be able to see their own accounts regardless of permissions.
+ if (TextUtils.isEmpty(type) && !isReadAccountsPermitted(callingUid, type)) {
+ return new Account[0];
+ }
+
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
@@ -2593,7 +2614,7 @@ public class AccountManagerService
logRecord(db, DebugDbHelper.ACTION_ACCOUNT_RENAME, TABLE_SHARED_ACCOUNTS,
sharedTableAccountId, accounts, callingUid);
// Recursively rename the account.
- renameAccountInternal(accounts, account, newName, callingUid);
+ renameAccountInternal(accounts, account, newName);
}
return r > 0;
}
@@ -2663,7 +2684,6 @@ public class AccountManagerService
@Override
public Account[] getAccountsByTypeForPackage(String type, String packageName) {
- checkBinderPermission(android.Manifest.permission.INTERACT_ACROSS_USERS);
int packageUid = -1;
try {
packageUid = AppGlobals.getPackageManager().getPackageUid(
@@ -2676,20 +2696,31 @@ public class AccountManagerService
}
@Override
- public void getAccountsByFeatures(IAccountManagerResponse response,
- String type, String[] features) {
+ public void getAccountsByFeatures(
+ IAccountManagerResponse response,
+ String type,
+ String[] features) {
+ int callingUid = Binder.getCallingUid();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "getAccounts: accountType " + type
+ ", response " + response
+ ", features " + stringArrayToString(features)
- + ", caller's uid " + Binder.getCallingUid()
+ + ", caller's uid " + callingUid
+ ", pid " + Binder.getCallingPid());
}
if (response == null) throw new IllegalArgumentException("response is null");
if (type == null) throw new IllegalArgumentException("accountType is null");
- checkReadAccountsPermission();
+ if (!isReadAccountsPermitted(callingUid, type)) {
+ Bundle result = new Bundle();
+ result.putParcelableArray(AccountManager.KEY_ACCOUNTS, new Account[0]);
+ try {
+ response.onResult(result);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Cannot respond to caller do to exception." , e);
+ }
+ return;
+ }
UserAccounts userAccounts = getUserAccountsForCaller();
- int callingUid = Binder.getCallingUid();
long identityToken = clearCallingIdentity();
try {
if (features == null || features.length == 0) {
@@ -2872,11 +2903,6 @@ public class AccountManagerService
}
}
- public void scheduleTimeout() {
- mMessageHandler.sendMessageDelayed(
- mMessageHandler.obtainMessage(MESSAGE_TIMED_OUT, this), TIMEOUT_DELAY_MS);
- }
-
public void cancelTimeout() {
mMessageHandler.removeMessages(MESSAGE_TIMED_OUT, this);
}
@@ -3181,12 +3207,9 @@ public class AccountManagerService
// who called.
private static String ACTION_CALLED_ACCOUNT_ADD = "action_called_account_add";
private static String ACTION_CALLED_ACCOUNT_REMOVE = "action_called_account_remove";
- private static String ACTION_CALLED_ACCOUNT_RENAME = "action_called_account_rename";
private static SimpleDateFormat dateFromat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- private static String UPDATE_WHERE_CLAUSE = KEY + "=?";
-
private static void createDebugTable(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_DEBUG + " ( "
+ ACCOUNTS_ID + " INTEGER,"
@@ -3421,7 +3444,7 @@ public class AccountManagerService
}
}
- public IBinder onBind(Intent intent) {
+ public IBinder onBind(@SuppressWarnings("unused") Intent intent) {
return asBinder();
}
@@ -3576,21 +3599,29 @@ public class AccountManagerService
}
}
- /** Succeeds if any of the specified permissions are granted. */
- private void checkBinderPermission(String... permissions) {
- final int uid = Binder.getCallingUid();
-
+ private boolean isPermitted(int callingUid, String... permissions) {
for (String perm : permissions) {
if (mContext.checkCallingOrSelfPermission(perm) == PackageManager.PERMISSION_GRANTED) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, " caller uid " + uid + " has " + perm);
+ Log.v(TAG, " caller uid " + callingUid + " has " + perm);
}
- return;
+ return true;
}
}
- String msg = "caller uid " + uid + " lacks any of " + TextUtils.join(",", permissions);
- Log.w(TAG, " " + msg);
- throw new SecurityException(msg);
+ return false;
+ }
+
+ /** Succeeds if any of the specified permissions are granted. */
+ private void checkBinderPermission(String... permissions) {
+ final int callingUid = Binder.getCallingUid();
+ if (isPermitted(callingUid, permissions)) {
+ String msg = String.format(
+ "caller uid %s lacks any of %s",
+ callingUid,
+ TextUtils.join(",", permissions));
+ Log.w(TAG, " " + msg);
+ throw new SecurityException(msg);
+ }
}
private int handleIncomingUser(int userId) {
@@ -3646,6 +3677,9 @@ public class AccountManagerService
}
private boolean isAccountManagedByCaller(String accountType, int callingUid) {
+ if (accountType == null) {
+ return false;
+ }
final int callingUserId = UserHandle.getUserId(callingUid);
for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo :
mAuthenticatorCache.getAllServices(callingUserId)) {
@@ -3723,20 +3757,34 @@ public class AccountManagerService
return false;
}
- private boolean isAccountOwnedByCallingUid(String accountType, int callingUid) {
- if (!isAccountManagedByCaller(accountType, callingUid)) {
- String msg = "caller uid " + callingUid + " is different than the authenticator's uid";
- Log.w(TAG, msg);
- return false;
- }
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "caller uid " + callingUid + " is the same as the authenticator's uid");
- }
- return true;
+ private boolean isReadAccountsPermitted(int callingUid, String accountType) {
+ /*
+ * Settings app (which is in the same uid as AcocuntManagerService), apps with the
+ * GET_ACCOUNTS permission or authenticators that own the account type should be able to
+ * access accounts of the specified account.
+ */
+ boolean isPermitted =
+ isPermitted(callingUid, Manifest.permission.GET_ACCOUNTS);
+ boolean isAccountManagedByCaller = isAccountManagedByCaller(accountType, callingUid);
+ Log.w(TAG, String.format(
+ "isReadAccountPermitted: isPermitted: %s, isAM: %s",
+ isPermitted,
+ isAccountManagedByCaller));
+ return isPermitted || isAccountManagedByCaller;
}
- private void checkReadAccountsPermission() {
- checkBinderPermission(Manifest.permission.GET_ACCOUNTS);
+ /** Succeeds if any of the specified permissions are granted. */
+ private void checkReadAccountsPermitted(
+ int callingUid,
+ String accountType) {
+ if (!isReadAccountsPermitted(callingUid, accountType)) {
+ String msg = String.format(
+ "caller uid %s cannot access %s accounts",
+ callingUid,
+ accountType);
+ Log.w(TAG, " " + msg);
+ throw new SecurityException(msg);
+ }
}
private boolean canUserModifyAccounts(int userId) {
@@ -4008,8 +4056,8 @@ public class AccountManagerService
String callingPackage,
byte[] pkgSigDigest) {
synchronized (accounts.cacheLock) {
- TokenCache cache = getTokenCacheForAccountLocked(accounts, account);
- return cache.get(tokenType, callingPackage, pkgSigDigest);
+ return accounts.accountTokenCaches.get(
+ account, tokenType, callingPackage, pkgSigDigest);
}
}
@@ -4094,17 +4142,6 @@ public class AccountManagerService
return authTokensForAccount;
}
- protected TokenCache getTokenCacheForAccountLocked(UserAccounts accounts, Account account) {
- WeakReference<TokenCache> cacheRef = accounts.accountTokenCaches.get(account);
- TokenCache cache;
- if (cacheRef == null || (cache = cacheRef.get()) == null) {
- cache = new TokenCache();
- cacheRef = new WeakReference<>(cache);
- accounts.accountTokenCaches.put(account, cacheRef);
- }
- return cache;
- }
-
private Context getContextForUser(UserHandle user) {
try {
return mContext.createPackageContextAsUser(mContext.getPackageName(), 0, user);
diff --git a/services/core/java/com/android/server/accounts/TokenCache.java b/services/core/java/com/android/server/accounts/TokenCache.java
index 70a7010..be91f98 100644
--- a/services/core/java/com/android/server/accounts/TokenCache.java
+++ b/services/core/java/com/android/server/accounts/TokenCache.java
@@ -16,6 +16,12 @@
package com.android.server.accounts;
+import android.accounts.Account;
+import android.util.LruCache;
+import android.util.Pair;
+
+import com.android.internal.util.Preconditions;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -23,10 +29,12 @@ import java.util.List;
import java.util.Objects;
/**
- * TokenCaches manage tokens associated with an account in memory.
+ * TokenCaches manage time limited authentication tokens in memory.
*/
/* default */ class TokenCache {
+ private static final int MAX_CACHE_CHARS = 64000;
+
private static class Value {
public final String token;
public final long expiryEpochMillis;
@@ -38,11 +46,13 @@ import java.util.Objects;
}
private static class Key {
+ public final Account account;
public final String packageName;
public final String tokenType;
public final byte[] sigDigest;
- public Key(String tokenType, String packageName, byte[] sigDigest) {
+ public Key(Account account, String tokenType, String packageName, byte[] sigDigest) {
+ this.account = account;
this.tokenType = tokenType;
this.packageName = packageName;
this.sigDigest = sigDigest;
@@ -52,7 +62,8 @@ import java.util.Objects;
public boolean equals(Object o) {
if (o != null && o instanceof Key) {
Key cacheKey = (Key) o;
- return Objects.equals(packageName, cacheKey.packageName)
+ return Objects.equals(account, cacheKey.account)
+ && Objects.equals(packageName, cacheKey.packageName)
&& Objects.equals(tokenType, cacheKey.tokenType)
&& Arrays.equals(sigDigest, cacheKey.sigDigest);
} else {
@@ -62,46 +73,109 @@ import java.util.Objects;
@Override
public int hashCode() {
- return packageName.hashCode() ^ tokenType.hashCode() ^ Arrays.hashCode(sigDigest);
+ return account.hashCode()
+ ^ packageName.hashCode()
+ ^ tokenType.hashCode()
+ ^ Arrays.hashCode(sigDigest);
}
}
- /**
- * Map associating basic token lookup information with with actual tokens (and optionally their
- * expiration times).
- */
- private HashMap<Key, Value> mCachedTokens = new HashMap<>();
+ private static class TokenLruCache extends LruCache<Key, Value> {
- /**
- * Map associated tokens with an Evictor that will manage evicting the token from the cache.
- * This reverse lookup is needed because very little information is given at token invalidation
- * time.
- */
- private HashMap<String, Evictor> mTokenEvictors = new HashMap<>();
+ private class Evictor {
+ private final List<Key> mKeys;
+
+ public Evictor() {
+ mKeys = new ArrayList<>();
+ }
+
+ public void add(Key k) {
+ mKeys.add(k);
+ }
+
+ public void evict() {
+ for (Key k : mKeys) {
+ TokenLruCache.this.remove(k);
+ }
+ }
+ }
+
+ /**
+ * Map associated tokens with an Evictor that will manage evicting the token from the
+ * cache. This reverse lookup is needed because very little information is given at token
+ * invalidation time.
+ */
+ private HashMap<Pair<String, String>, Evictor> mTokenEvictors = new HashMap<>();
+ private HashMap<Account, Evictor> mAccountEvictors = new HashMap<>();
+
+ public TokenLruCache() {
+ super(MAX_CACHE_CHARS);
+ }
+
+ @Override
+ protected int sizeOf(Key k, Value v) {
+ return v.token.length();
+ }
+
+ @Override
+ protected void entryRemoved(boolean evicted, Key k, Value oldVal, Value newVal) {
+ // When a token has been removed, clean up the associated Evictor.
+ if (oldVal != null && newVal == null) {
+ /*
+ * This is recursive, but it won't spiral out of control because LruCache is
+ * thread safe and the Evictor can only be removed once.
+ */
+ Evictor evictor = mTokenEvictors.remove(oldVal.token);
+ if (evictor != null) {
+ evictor.evict();
+ }
+ }
+ }
- private class Evictor {
- private final String mToken;
- private final List<Key> mKeys;
+ public void putToken(Key k, Value v) {
+ // Prepare for removal by token string.
+ Evictor tokenEvictor = mTokenEvictors.get(v.token);
+ if (tokenEvictor == null) {
+ tokenEvictor = new Evictor();
+ }
+ tokenEvictor.add(k);
+ mTokenEvictors.put(new Pair<>(k.account.type, v.token), tokenEvictor);
- public Evictor(String token) {
- mKeys = new ArrayList<>();
- mToken = token;
+ // Prepare for removal by associated account.
+ Evictor accountEvictor = mAccountEvictors.get(k.account);
+ if (accountEvictor == null) {
+ accountEvictor = new Evictor();
+ }
+ accountEvictor.add(k);
+ mAccountEvictors.put(k.account, tokenEvictor);
+
+ // Only cache the token once we can remove it directly or by account.
+ put(k, v);
}
- public void add(Key k) {
- mKeys.add(k);
+ public void evict(String accountType, String token) {
+ Evictor evictor = mTokenEvictors.get(new Pair<>(accountType, token));
+ if (evictor != null) {
+ evictor.evict();
+ }
+
}
- public void evict() {
- for (Key k : mKeys) {
- mCachedTokens.remove(k);
+ public void evict(Account account) {
+ Evictor evictor = mAccountEvictors.get(account);
+ if (evictor != null) {
+ evictor.evict();
}
- // Clear out the evictor reference.
- mTokenEvictors.remove(mToken);
}
}
/**
+ * Map associating basic token lookup information with with actual tokens (and optionally their
+ * expiration times).
+ */
+ private TokenLruCache mCachedTokens = new TokenLruCache();
+
+ /**
* Caches the specified token until the specified expiryMillis. The token will be associated
* with the given token type, package name, and digest of signatures.
*
@@ -112,51 +186,44 @@ import java.util.Objects;
* @param expiryMillis
*/
public void put(
+ Account account,
String token,
String tokenType,
String packageName,
byte[] sigDigest,
long expiryMillis) {
+ Preconditions.checkNotNull(account);
if (token == null || System.currentTimeMillis() > expiryMillis) {
return;
}
- Key k = new Key(tokenType, packageName, sigDigest);
- // Prep evictor. No token should be cached without a corresponding evictor.
- Evictor evictor = mTokenEvictors.get(token);
- if (evictor == null) {
- evictor = new Evictor(token);
- }
- evictor.add(k);
- mTokenEvictors.put(token, evictor);
- // Then cache values.
+ Key k = new Key(account, tokenType, packageName, sigDigest);
Value v = new Value(token, expiryMillis);
- mCachedTokens.put(k, v);
+ mCachedTokens.putToken(k, v);
}
/**
* Evicts the specified token from the cache. This should be called as part of a token
* invalidation workflow.
*/
- public void remove(String token) {
- Evictor evictor = mTokenEvictors.get(token);
- if (evictor == null) {
- // This condition is expected if the token isn't cached.
- return;
- }
- evictor.evict();
+ public void remove(String accountType, String token) {
+ mCachedTokens.evict(accountType, token);
+ }
+
+ public void remove(Account account) {
+ mCachedTokens.evict(account);
}
/**
* Gets a token from the cache if possible.
*/
- public String get(String tokenType, String packageName, byte[] sigDigest) {
- Key k = new Key(tokenType, packageName, sigDigest);
+ public String get(Account account, String tokenType, String packageName, byte[] sigDigest) {
+ Key k = new Key(account, tokenType, packageName, sigDigest);
Value v = mCachedTokens.get(k);
long currentTime = System.currentTimeMillis();
if (v != null && currentTime < v.expiryEpochMillis) {
return v.token;
} else if (v != null) {
- remove(v.token);
+ remove(account.type, v.token);
}
return null;
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 333db5d..899139f 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -29,6 +29,7 @@ import java.util.List;
import java.util.Set;
import android.app.ActivityThread;
+import android.app.AppOpsManager;
import android.os.Build;
import android.os.DeadObjectException;
import android.os.Handler;
@@ -302,8 +303,8 @@ public final class ActiveServices {
return getServiceMap(callingUser).mServicesByName;
}
- ComponentName startServiceLocked(IApplicationThread caller, Intent service,
- String resolvedType, int callingPid, int callingUid, int userId)
+ ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
+ int callingPid, int callingUid, String callingPackage, int userId)
throws TransactionTooLargeException {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
+ " type=" + resolvedType + " args=" + service.getExtras());
@@ -324,7 +325,7 @@ public final class ActiveServices {
ServiceLookupResult res =
- retrieveServiceLocked(service, resolvedType,
+ retrieveServiceLocked(service, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg);
if (res == null) {
return null;
@@ -490,7 +491,7 @@ public final class ActiveServices {
}
// If this service is active, make sure it is stopped.
- ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
+ ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, null,
Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false);
if (r != null) {
if (r.record != null) {
@@ -508,8 +509,8 @@ public final class ActiveServices {
return 0;
}
- IBinder peekServiceLocked(Intent service, String resolvedType) {
- ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
+ IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) {
+ ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, callingPackage,
Binder.getCallingPid(), Binder.getCallingUid(),
UserHandle.getCallingUserId(), false, false);
@@ -694,8 +695,8 @@ public final class ActiveServices {
}
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
- String resolvedType, IServiceConnection connection, int flags, int userId)
- throws TransactionTooLargeException {
+ String resolvedType, IServiceConnection connection, int flags,
+ String callingPackage, int userId) throws TransactionTooLargeException {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service
+ " type=" + resolvedType + " conn=" + connection.asBinder()
+ " flags=0x" + Integer.toHexString(flags));
@@ -746,7 +747,7 @@ public final class ActiveServices {
final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
ServiceLookupResult res =
- retrieveServiceLocked(service, resolvedType,
+ retrieveServiceLocked(service, resolvedType, callingPackage,
Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
if (res == null) {
return 0;
@@ -1022,7 +1023,7 @@ public final class ActiveServices {
}
private ServiceLookupResult retrieveServiceLocked(Intent service,
- String resolvedType, int callingPid, int callingUid, int userId,
+ String resolvedType, String callingPackage, int callingPid, int callingUid, int userId,
boolean createIfNeeded, boolean callingFromFg) {
ServiceRecord r = null;
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "retrieveServiceLocked: " + service
@@ -1112,7 +1113,18 @@ public final class ActiveServices {
+ ", uid=" + callingUid
+ " requires " + r.permission);
return new ServiceLookupResult(null, r.permission);
+ } else if (r.permission != null && callingPackage != null) {
+ final int opCode = AppOpsManager.permissionToOpCode(r.permission);
+ if (opCode != AppOpsManager.OP_NONE && mAm.mAppOpsService.noteOperation(
+ opCode, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) {
+ Slog.w(TAG, "Appop Denial: Accessing service " + r.name
+ + " from pid=" + callingPid
+ + ", uid=" + callingUid
+ + " requires appop " + AppOpsManager.opToName(opCode));
+ return null;
+ }
}
+
if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
resolvedType, r.appInfo)) {
return null;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f031694..477c26c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -142,6 +142,7 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.backup.IBackupManager;
+import android.app.admin.DevicePolicyManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ClipData;
@@ -3209,13 +3210,14 @@ public final class ActivityManagerService extends ActivityManagerNative
int uid = app.uid;
int[] gids = null;
- int mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
+ int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
if (!app.isolated) {
int[] permGids = null;
try {
checkTime(startTime, "startProcess: getting gids from package manager");
- permGids = AppGlobals.getPackageManager().getPackageGids(app.info.packageName,
- app.userId);
+ final IPackageManager pm = AppGlobals.getPackageManager();
+ permGids = pm.getPackageGids(app.info.packageName, app.userId);
+ mountExternal = pm.getMountExternalMode(uid);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -10688,6 +10690,21 @@ public final class ActivityManagerService extends ActivityManagerNative
}
@Override
+ public boolean isScreenCaptureAllowedOnCurrentActivity() {
+ int userId = mCurrentUserId;
+ synchronized (this) {
+ ActivityRecord activity = getFocusedStack().topActivity();
+ if (activity == null) {
+ return false;
+ }
+ userId = activity.userId;
+ }
+ DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
+ Context.DEVICE_POLICY_SERVICE);
+ return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
+ }
+
+ @Override
public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId(),
null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT);
@@ -15535,13 +15552,18 @@ public final class ActivityManagerService extends ActivityManagerNative
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
- String resolvedType, int userId) throws TransactionTooLargeException {
+ String resolvedType, String callingPackage, int userId)
+ throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
+ if (callingPackage == null) {
+ throw new IllegalArgumentException("callingPackage cannot be null");
+ }
+
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"startService: " + service + " type=" + resolvedType);
synchronized(this) {
@@ -15549,20 +15571,21 @@ public final class ActivityManagerService extends ActivityManagerNative
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res = mServices.startServiceLocked(caller, service,
- resolvedType, callingPid, callingUid, userId);
+ resolvedType, callingPid, callingUid, callingPackage, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}
- ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, int userId)
+ ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
+ String callingPackage, int userId)
throws TransactionTooLargeException {
synchronized(this) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"startServiceInPackage: " + service + " type=" + resolvedType);
final long origId = Binder.clearCallingIdentity();
ComponentName res = mServices.startServiceLocked(null, service,
- resolvedType, -1, uid, userId);
+ resolvedType, -1, uid, callingPackage, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
@@ -15583,14 +15606,19 @@ public final class ActivityManagerService extends ActivityManagerNative
}
@Override
- public IBinder peekService(Intent service, String resolvedType) {
+ public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
enforceNotIsolatedCaller("peekService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
+
+ if (callingPackage == null) {
+ throw new IllegalArgumentException("callingPackage cannot be null");
+ }
+
synchronized(this) {
- return mServices.peekServiceLocked(service, resolvedType);
+ return mServices.peekServiceLocked(service, resolvedType, callingPackage);
}
}
@@ -15760,8 +15788,8 @@ public final class ActivityManagerService extends ActivityManagerNative
}
public int bindService(IApplicationThread caller, IBinder token, Intent service,
- String resolvedType, IServiceConnection connection, int flags, int userId)
- throws TransactionTooLargeException {
+ String resolvedType, IServiceConnection connection, int flags, String callingPackage,
+ int userId) throws TransactionTooLargeException {
enforceNotIsolatedCaller("bindService");
// Refuse possible leaked file descriptors
@@ -15769,9 +15797,13 @@ public final class ActivityManagerService extends ActivityManagerNative
throw new IllegalArgumentException("File descriptors passed in Intent");
}
+ if (callingPackage == null) {
+ throw new IllegalArgumentException("callingPackage cannot be null");
+ }
+
synchronized(this) {
- return mServices.bindServiceLocked(caller, token, service, resolvedType,
- connection, flags, userId);
+ return mServices.bindServiceLocked(caller, token, service,
+ resolvedType, connection, flags, callingPackage, userId);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 0714d36..8c3a950 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -2829,7 +2829,7 @@ final class ActivityStack {
+ " res=" + resultCode + " data=" + resultData);
if (resultTo.userId != r.userId) {
if (resultData != null) {
- resultData.setContentUserHint(r.userId);
+ resultData.prepareToLeaveUser(r.userId);
}
}
if (r.info.applicationInfo.uid > 0) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 4ce5c7e..c12aff6 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -187,12 +187,12 @@ public final class ActivityStackSupervisor implements DisplayListener {
Manifest.permission.CALL_PHONE);
}
- /** Action not restricted for the calling package. */
- private static final int ACTION_RESTRICTION_NONE = 0;
- /** Action restricted for the calling package by not granting a used permission. */
- private static final int ACTION_RESTRICTION_PERMISSION = 1;
- /** Action restricted for the calling package by not allowing a used permission's app op. */
- private static final int ACTION_RESTRICTION_APPOP = 2;
+ /** Action restriction: launching the activity is not restricted. */
+ private static final int ACTIVITY_RESTRICTION_NONE = 0;
+ /** Action restriction: launching the activity is restricted by a permission. */
+ private static final int ACTIVITY_RESTRICTION_PERMISSION = 1;
+ /** Action restriction: launching the activity is restricted by an app op. */
+ private static final int ACTIVITY_RESTRICTION_APPOP = 2;
/** Status Bar Service **/
private IBinder mToken = new Binder();
@@ -1539,51 +1539,61 @@ public final class ActivityStackSupervisor implements DisplayListener {
return err;
}
+ boolean abort = false;
+
final int startAnyPerm = mService.checkPermission(
START_ANY_ACTIVITY, callingPid, callingUid);
- final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
- callingUid, aInfo.applicationInfo.uid, aInfo.exported);
- final int actionRestriction = getActionRestrictionForCallingPackage(
- intent.getAction(), callingPackage, callingPid, callingUid);
- if (startAnyPerm != PERMISSION_GRANTED && (componentPerm != PERMISSION_GRANTED
- || actionRestriction == ACTION_RESTRICTION_PERMISSION)) {
- if (resultRecord != null) {
- resultStack.sendActivityResultLocked(-1,
- resultRecord, resultWho, requestCode,
- Activity.RESULT_CANCELED, null);
+ if (startAnyPerm != PERMISSION_GRANTED) {
+ final int componentRestriction = getComponentRestrictionForCallingPackage(
+ aInfo, callingPackage, callingPid, callingUid);
+ final int actionRestriction = getActionRestrictionForCallingPackage(
+ intent.getAction(), callingPackage, callingPid, callingUid);
+
+ if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION
+ || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
+ if (resultRecord != null) {
+ resultStack.sendActivityResultLocked(-1,
+ resultRecord, resultWho, requestCode,
+ Activity.RESULT_CANCELED, null);
+ }
+ String msg;
+ if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
+ msg = "Permission Denial: starting " + intent.toString()
+ + " from " + callerApp + " (pid=" + callingPid
+ + ", uid=" + callingUid + ")" + " with revoked permission "
+ + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction());
+ } else if (!aInfo.exported) {
+ msg = "Permission Denial: starting " + intent.toString()
+ + " from " + callerApp + " (pid=" + callingPid
+ + ", uid=" + callingUid + ")"
+ + " not exported from uid " + aInfo.applicationInfo.uid;
+ } else {
+ msg = "Permission Denial: starting " + intent.toString()
+ + " from " + callerApp + " (pid=" + callingPid
+ + ", uid=" + callingUid + ")"
+ + " requires " + aInfo.permission;
+ }
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
}
- String msg;
- if (actionRestriction == ACTION_RESTRICTION_PERMISSION) {
- msg = "Permission Denial: starting " + intent.toString()
- + " from " + callerApp + " (pid=" + callingPid
- + ", uid=" + callingUid + ")" + " with revoked permission "
- + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction());
- } else if (!aInfo.exported) {
- msg = "Permission Denial: starting " + intent.toString()
+
+ if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) {
+ String message = "Appop Denial: starting " + intent.toString()
+ " from " + callerApp + " (pid=" + callingPid
+ ", uid=" + callingUid + ")"
- + " not exported from uid " + aInfo.applicationInfo.uid;
- } else {
- msg = "Permission Denial: starting " + intent.toString()
+ + " requires " + AppOpsManager.permissionToOp(
+ ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()));
+ Slog.w(TAG, message);
+ abort = true;
+ } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) {
+ String message = "Appop Denial: starting " + intent.toString()
+ " from " + callerApp + " (pid=" + callingPid
+ ", uid=" + callingUid + ")"
- + " requires " + aInfo.permission;
+ + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission);
+ Slog.w(TAG, message);
+ abort = true;
}
- Slog.w(TAG, msg);
- throw new SecurityException(msg);
- }
-
- boolean abort = false;
-
- if (startAnyPerm != PERMISSION_GRANTED
- && actionRestriction == ACTION_RESTRICTION_APPOP) {
- String msg = "Permission Denial: starting " + intent.toString()
- + " from " + callerApp + " (pid=" + callingPid
- + ", uid=" + callingUid + ")"
- + " requires " + aInfo.permission;
- Slog.w(TAG, msg);
- abort = true;
}
abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
@@ -1664,15 +1674,40 @@ public final class ActivityStackSupervisor implements DisplayListener {
return err;
}
+ private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo,
+ String callingPackage, int callingPid, int callingUid) {
+ if (activityInfo.permission == null) {
+ return ACTIVITY_RESTRICTION_NONE;
+ }
+
+ if (mService.checkComponentPermission(activityInfo.permission, callingPid, callingUid,
+ activityInfo.applicationInfo.uid, activityInfo.exported)
+ == PackageManager.PERMISSION_DENIED) {
+ return ACTIVITY_RESTRICTION_PERMISSION;
+ }
+
+ final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission);
+ if (opCode == AppOpsManager.OP_NONE) {
+ return ACTIVITY_RESTRICTION_NONE;
+ }
+
+ if (mService.mAppOpsService.noteOperation(opCode, callingUid,
+ callingPackage) != AppOpsManager.MODE_ALLOWED) {
+ return ACTIVITY_RESTRICTION_APPOP;
+ }
+
+ return ACTIVITY_RESTRICTION_NONE;
+ }
+
private int getActionRestrictionForCallingPackage(String action,
String callingPackage, int callingPid, int callingUid) {
if (action == null) {
- return ACTION_RESTRICTION_NONE;
+ return ACTIVITY_RESTRICTION_NONE;
}
String permission = ACTION_TO_RUNTIME_PERMISSION.get(action);
if (permission == null) {
- return ACTION_RESTRICTION_NONE;
+ return ACTIVITY_RESTRICTION_NONE;
}
final PackageInfo packageInfo;
@@ -1681,29 +1716,29 @@ public final class ActivityStackSupervisor implements DisplayListener {
.getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS);
} catch (PackageManager.NameNotFoundException e) {
Slog.i(TAG, "Cannot find package info for " + callingPackage);
- return ACTION_RESTRICTION_NONE;
+ return ACTIVITY_RESTRICTION_NONE;
}
if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) {
- return ACTION_RESTRICTION_NONE;
+ return ACTIVITY_RESTRICTION_NONE;
}
if (mService.checkPermission(permission, callingPid, callingUid) ==
PackageManager.PERMISSION_DENIED) {
- return ACTION_RESTRICTION_PERMISSION;
+ return ACTIVITY_RESTRICTION_PERMISSION;
}
final int opCode = AppOpsManager.permissionToOpCode(permission);
if (opCode == AppOpsManager.OP_NONE) {
- return ACTION_RESTRICTION_NONE;
+ return ACTIVITY_RESTRICTION_NONE;
}
if (mService.mAppOpsService.noteOperation(opCode, callingUid,
callingPackage) != AppOpsManager.MODE_ALLOWED) {
- return ACTION_RESTRICTION_APPOP;
+ return ACTIVITY_RESTRICTION_APPOP;
}
- return ACTION_RESTRICTION_NONE;
+ return ACTIVITY_RESTRICTION_NONE;
}
ActivityStack computeStackFocus(ActivityRecord r, boolean newTask) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 78557634..6cc1b11 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -864,8 +864,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
}
final class WakeupReasonThread extends Thread {
- final int[] mIrqs = new int[32];
- final String[] mReasons = new String[32];
+ final String[] mReason = new String[1];
WakeupReasonThread() {
super("BatteryStats_wakeupReason");
@@ -876,12 +875,11 @@ public final class BatteryStatsService extends IBatteryStats.Stub
try {
int num;
- while ((num=nativeWaitWakeup(mIrqs, mReasons)) >= 0) {
+ while ((num = nativeWaitWakeup(mReason)) >= 0) {
synchronized (mStats) {
+ // num will be either 0 or 1.
if (num > 0) {
- for (int i=0; i<num; i++) {
- mStats.noteWakeupReasonLocked(mReasons[i]);
- }
+ mStats.noteWakeupReasonLocked(mReason[0]);
} else {
mStats.noteWakeupReasonLocked("unknown");
}
@@ -893,7 +891,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
}
}
- private static native int nativeWaitWakeup(int[] outIrqs, String[] outReasons);
+ private static native int nativeWaitWakeup(String[] outReason);
private void dumpHelp(PrintWriter pw) {
pw.println("Battery stats (batterystats) dump options:");
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 2335071..30aa411 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -463,7 +463,7 @@ public final class BroadcastQueue {
}
}
- private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
+ private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
BroadcastFilter filter, boolean ordered) {
boolean skip = false;
if (filter.requiredPermission != null) {
@@ -477,9 +477,23 @@ public final class BroadcastQueue {
+ " requires " + filter.requiredPermission
+ " due to registered receiver " + filter);
skip = true;
+ } else {
+ final int opCode = AppOpsManager.permissionToOpCode(filter.requiredPermission);
+ if (opCode != AppOpsManager.OP_NONE
+ && mService.mAppOpsService.noteOperation(opCode, r.callingUid,
+ r.callerPackage) != AppOpsManager.MODE_ALLOWED) {
+ Slog.w(TAG, "Appop Denial: broadcasting "
+ + r.intent.toString()
+ + " from " + r.callerPackage + " (pid="
+ + r.callingPid + ", uid=" + r.callingUid + ")"
+ + " requires appop " + AppOpsManager.permissionToOp(
+ filter.requiredPermission)
+ + " due to registered receiver " + filter);
+ skip = true;
+ }
}
}
- if (!skip && r.requiredPermission != null) {
+ if (!skip) {
int perm = mService.checkComponentPermission(r.requiredPermission,
filter.receiverList.pid, filter.receiverList.uid, -1, true);
if (perm != PackageManager.PERMISSION_GRANTED) {
@@ -493,17 +507,42 @@ public final class BroadcastQueue {
+ " (uid " + r.callingUid + ")");
skip = true;
}
- }
- if (r.appOp != AppOpsManager.OP_NONE) {
- int mode = mService.mAppOpsService.noteOperation(r.appOp,
- filter.receiverList.uid, filter.packageName);
- if (mode != AppOpsManager.MODE_ALLOWED) {
- if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
- "App op " + r.appOp + " not allowed for broadcast to uid "
- + filter.receiverList.uid + " pkg " + filter.packageName);
- skip = true;
+ int appOp = AppOpsManager.OP_NONE;
+ if (r.requiredPermission != null) {
+ appOp = AppOpsManager.permissionToOpCode(r.requiredPermission);
+ if (appOp != AppOpsManager.OP_NONE
+ && mService.mAppOpsService.noteOperation(appOp,
+ filter.receiverList.uid, filter.packageName)
+ != AppOpsManager.MODE_ALLOWED) {
+ Slog.w(TAG, "Appop Denial: receiving "
+ + r.intent.toString()
+ + " to " + filter.receiverList.app
+ + " (pid=" + filter.receiverList.pid
+ + ", uid=" + filter.receiverList.uid + ")"
+ + " requires appop " + AppOpsManager.permissionToOp(
+ r.requiredPermission)
+ + " due to sender " + r.callerPackage
+ + " (uid " + r.callingUid + ")");
+ skip = true;
+ }
+ }
+ if (!skip && r.appOp != appOp && r.appOp != AppOpsManager.OP_NONE
+ && mService.mAppOpsService.noteOperation(r.appOp,
+ filter.receiverList.uid, filter.packageName)
+ != AppOpsManager.MODE_ALLOWED) {
+ Slog.w(TAG, "Appop Denial: receiving "
+ + r.intent.toString()
+ + " to " + filter.receiverList.app
+ + " (pid=" + filter.receiverList.pid
+ + ", uid=" + filter.receiverList.uid + ")"
+ + " requires appop " + AppOpsManager.permissionToOp(
+ r.requiredPermission)
+ + " due to sender " + r.callerPackage
+ + " (uid " + r.callingUid + ")");
+ skip = true;
}
}
+
if (!skip) {
skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
r.callingPid, r.resolvedType, filter.receiverList.uid);
@@ -804,8 +843,23 @@ public final class BroadcastQueue {
+ " due to receiver " + component.flattenToShortString());
}
skip = true;
+ } else if (info.activityInfo.permission != null) {
+ final int opCode = AppOpsManager.permissionToOpCode(info.activityInfo.permission);
+ if (opCode != AppOpsManager.OP_NONE
+ && mService.mAppOpsService.noteOperation(opCode, r.callingUid,
+ r.callerPackage) != AppOpsManager.MODE_ALLOWED) {
+ Slog.w(TAG, "Appop Denial: broadcasting "
+ + r.intent.toString()
+ + " from " + r.callerPackage + " (pid="
+ + r.callingPid + ", uid=" + r.callingUid + ")"
+ + " requires appop " + AppOpsManager.permissionToOp(
+ info.activityInfo.permission)
+ + " due to registered receiver "
+ + component.flattenToShortString());
+ skip = true;
+ }
}
- if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
+ if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
r.requiredPermission != null) {
try {
perm = AppGlobals.getPackageManager().
@@ -825,17 +879,36 @@ public final class BroadcastQueue {
skip = true;
}
}
- if (r.appOp != AppOpsManager.OP_NONE) {
- int mode = mService.mAppOpsService.noteOperation(r.appOp,
- info.activityInfo.applicationInfo.uid, info.activityInfo.packageName);
- if (mode != AppOpsManager.MODE_ALLOWED) {
- if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
- "App op " + r.appOp + " not allowed for broadcast to uid "
- + info.activityInfo.applicationInfo.uid + " pkg "
- + info.activityInfo.packageName);
+ int appOp = AppOpsManager.OP_NONE;
+ if (!skip && r.requiredPermission != null) {
+ appOp = AppOpsManager.permissionToOpCode(r.requiredPermission);
+ if (appOp != AppOpsManager.OP_NONE
+ && mService.mAppOpsService.noteOperation(appOp,
+ info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
+ != AppOpsManager.MODE_ALLOWED) {
+ Slog.w(TAG, "Appop Denial: receiving "
+ + r.intent + " to "
+ + component.flattenToShortString()
+ + " requires appop " + AppOpsManager.permissionToOp(
+ r.requiredPermission)
+ + " due to sender " + r.callerPackage
+ + " (uid " + r.callingUid + ")");
skip = true;
}
}
+ if (!skip && r.appOp != appOp && r.appOp != AppOpsManager.OP_NONE
+ && mService.mAppOpsService.noteOperation(r.appOp,
+ info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
+ != AppOpsManager.MODE_ALLOWED) {
+ Slog.w(TAG, "Appop Denial: receiving "
+ + r.intent + " to "
+ + component.flattenToShortString()
+ + " requires appop " + AppOpsManager.permissionToOp(
+ r.requiredPermission)
+ + " due to sender " + r.callerPackage
+ + " (uid " + r.callingUid + ")");
+ skip = true;
+ }
if (!skip) {
skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index ece3ffb..5b46799 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -305,7 +305,8 @@ final class PendingIntentRecord extends IIntentSender.Stub {
break;
case ActivityManager.INTENT_SENDER_SERVICE:
try {
- owner.startServiceInPackage(uid, finalIntent, resolvedType, userId);
+ owner.startServiceInPackage(uid, finalIntent,
+ resolvedType, key.packageName, userId);
} catch (RuntimeException e) {
Slog.w(TAG, "Unable to send startService intent", e);
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 0dc4076..dd4111d 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -3791,6 +3791,8 @@ public class AudioService extends IAudioService.Stub {
// fire changed intents for all streams
mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
+ mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
+ mStreamVolumeAlias[mStreamType]);
sendBroadcastToAll(mVolumeChanged);
}
return changed;
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index 99a0567..e472928 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -47,6 +47,9 @@ import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.LocalLog;
+import android.util.LocalLog.ReadOnlyLocalLog;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -57,6 +60,7 @@ import com.android.server.connectivity.NetworkAgentInfo;
import java.io.IOException;
import java.net.HttpURLConnection;
+import java.net.InetAddress;
import java.net.URL;
import java.util.List;
import java.util.Random;
@@ -232,6 +236,8 @@ public class NetworkMonitor extends StateMachine {
private CustomIntentReceiver mLaunchCaptivePortalAppBroadcastReceiver = null;
private String mCaptivePortalLoggedInResponseToken = null;
+ private final LocalLog validationLogs = new LocalLog(20); // 20 lines
+
public NetworkMonitor(Context context, Handler handler, NetworkAgentInfo networkAgentInfo,
NetworkRequest defaultRequest) {
// Add suffix indicating which NetworkMonitor we're talking about.
@@ -269,7 +275,16 @@ public class NetworkMonitor extends StateMachine {
@Override
protected void log(String s) {
- Log.d(TAG + "/" + mNetworkAgentInfo.name(), s);
+ if (DBG) Log.d(TAG + "/" + mNetworkAgentInfo.name(), s);
+ }
+
+ private void validationLog(String s) {
+ if (DBG) log(s);
+ validationLogs.log(s);
+ }
+
+ public ReadOnlyLocalLog getValidationLogs() {
+ return validationLogs.readOnlyLocalLog();
}
// DefaultState is the parent of all States. It exists only to handle CMD_* messages but
@@ -277,18 +292,15 @@ public class NetworkMonitor extends StateMachine {
private class DefaultState extends State {
@Override
public boolean processMessage(Message message) {
- if (DBG) log(getName() + message.toString());
switch (message.what) {
case CMD_NETWORK_LINGER:
- if (DBG) log("Lingering");
+ log("Lingering");
transitionTo(mLingeringState);
return HANDLED;
case CMD_NETWORK_CONNECTED:
- if (DBG) log("Connected");
transitionTo(mEvaluatingState);
return HANDLED;
case CMD_NETWORK_DISCONNECTED:
- if (DBG) log("Disconnected - quitting");
if (mLaunchCaptivePortalAppBroadcastReceiver != null) {
mContext.unregisterReceiver(mLaunchCaptivePortalAppBroadcastReceiver);
mLaunchCaptivePortalAppBroadcastReceiver = null;
@@ -297,13 +309,14 @@ public class NetworkMonitor extends StateMachine {
return HANDLED;
case CMD_FORCE_REEVALUATION:
case CMD_CAPTIVE_PORTAL_RECHECK:
- if (DBG) log("Forcing reevaluation");
+ log("Forcing reevaluation for UID " + message.arg1);
mUidResponsibleForReeval = message.arg1;
transitionTo(mEvaluatingState);
return HANDLED;
case CMD_CAPTIVE_PORTAL_APP_FINISHED:
if (!mCaptivePortalLoggedInResponseToken.equals((String)message.obj))
return HANDLED;
+ log("CaptivePortal App responded with " + message.arg1);
// Previous token was sent out, come up with a new one.
mCaptivePortalLoggedInResponseToken = String.valueOf(new Random().nextLong());
switch (message.arg1) {
@@ -341,14 +354,12 @@ public class NetworkMonitor extends StateMachine {
private class ValidatedState extends State {
@Override
public void enter() {
- if (DBG) log("Validated");
mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED,
NETWORK_TEST_RESULT_VALID, 0, mNetworkAgentInfo));
}
@Override
public boolean processMessage(Message message) {
- if (DBG) log(getName() + message.toString());
switch (message.what) {
case CMD_NETWORK_CONNECTED:
transitionTo(mValidatedState);
@@ -364,7 +375,6 @@ public class NetworkMonitor extends StateMachine {
private class MaybeNotifyState extends State {
@Override
public boolean processMessage(Message message) {
- if (DBG) log(getName() + message.toString());
switch (message.what) {
case CMD_LAUNCH_CAPTIVE_PORTAL_APP:
final Intent intent = new Intent(
@@ -408,7 +418,6 @@ public class NetworkMonitor extends StateMachine {
@Override
public boolean processMessage(Message message) {
- if (DBG) log(getName() + message.toString());
switch (message.what) {
case CMD_REEVALUATE:
if (message.arg1 != mReevaluateToken || mUserDoesNotWant)
@@ -533,12 +542,6 @@ public class NetworkMonitor extends StateMachine {
}
@Override
- public boolean processMessage(Message message) {
- if (DBG) log(getName() + message.toString());
- return NOT_HANDLED;
- }
-
- @Override
public void exit() {
removeMessages(CMD_CAPTIVE_PORTAL_RECHECK);
}
@@ -570,9 +573,9 @@ public class NetworkMonitor extends StateMachine {
@Override
public boolean processMessage(Message message) {
- if (DBG) log(getName() + message.toString());
switch (message.what) {
case CMD_NETWORK_CONNECTED:
+ log("Unlingered");
// Go straight to active as we've already evaluated.
transitionTo(mValidatedState);
return HANDLED;
@@ -642,17 +645,31 @@ public class NetworkMonitor extends StateMachine {
// fact block fetching of the generate_204 URL which would lead to false negative
// results for network validation.
boolean fetchPac = false;
- {
- final ProxyInfo proxyInfo = mNetworkAgentInfo.linkProperties.getHttpProxy();
- if (proxyInfo != null && !Uri.EMPTY.equals(proxyInfo.getPacFileUrl())) {
- url = new URL(proxyInfo.getPacFileUrl().toString());
- fetchPac = true;
- }
+ final ProxyInfo proxyInfo = mNetworkAgentInfo.linkProperties.getHttpProxy();
+ if (proxyInfo != null && !Uri.EMPTY.equals(proxyInfo.getPacFileUrl())) {
+ url = new URL(proxyInfo.getPacFileUrl().toString());
+ fetchPac = true;
}
- if (DBG) {
- log("Checking " + url.toString() + " on " +
- mNetworkAgentInfo.networkInfo.getExtraInfo());
+ final StringBuffer connectInfo = new StringBuffer();
+ String hostToResolve = null;
+ // Only resolve a host if HttpURLConnection is about to, to avoid any potentially
+ // unnecessary resolution.
+ if (proxyInfo == null || fetchPac) {
+ hostToResolve = url.getHost();
+ } else if (proxyInfo != null) {
+ hostToResolve = proxyInfo.getHost();
}
+ if (!TextUtils.isEmpty(hostToResolve)) {
+ connectInfo.append(", " + hostToResolve + "=");
+ final InetAddress[] addresses =
+ mNetworkAgentInfo.network.getAllByName(hostToResolve);
+ for (InetAddress address : addresses) {
+ connectInfo.append(address.getHostAddress());
+ if (address != addresses[addresses.length-1]) connectInfo.append(",");
+ }
+ }
+ validationLog("Checking " + url.toString() + " on " +
+ mNetworkAgentInfo.networkInfo.getExtraInfo() + connectInfo);
urlConnection = (HttpURLConnection) mNetworkAgentInfo.network.openConnection(url);
urlConnection.setInstanceFollowRedirects(fetchPac);
urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
@@ -668,10 +685,8 @@ public class NetworkMonitor extends StateMachine {
long responseTimestamp = SystemClock.elapsedRealtime();
httpResponseCode = urlConnection.getResponseCode();
- if (DBG) {
- log("isCaptivePortal: ret=" + httpResponseCode +
- " headers=" + urlConnection.getHeaderFields());
- }
+ validationLog("isCaptivePortal: ret=" + httpResponseCode +
+ " headers=" + urlConnection.getHeaderFields());
// NOTE: We may want to consider an "HTTP/1.0 204" response to be a captive
// portal. The only example of this seen so far was a captive portal. For
// the time being go with prior behavior of assuming it's not a captive
@@ -684,12 +699,12 @@ public class NetworkMonitor extends StateMachine {
// sign-in to an empty page. Probably the result of a broken transparent proxy.
// See http://b/9972012.
if (httpResponseCode == 200 && urlConnection.getContentLength() == 0) {
- if (DBG) log("Empty 200 response interpreted as 204 response.");
+ validationLog("Empty 200 response interpreted as 204 response.");
httpResponseCode = 204;
}
if (httpResponseCode == 200 && fetchPac) {
- if (DBG) log("PAC fetch 200 response interpreted as 204 response.");
+ validationLog("PAC fetch 200 response interpreted as 204 response.");
httpResponseCode = 204;
}
@@ -697,7 +712,7 @@ public class NetworkMonitor extends StateMachine {
httpResponseCode != 204 /* isCaptivePortal */,
requestTimestamp, responseTimestamp);
} catch (IOException e) {
- if (DBG) log("Probably not a portal: exception " + e);
+ validationLog("Probably not a portal: exception " + e);
if (httpResponseCode == 599) {
// TODO: Ping gateway and DNS server and log results.
}
@@ -720,7 +735,6 @@ public class NetworkMonitor extends StateMachine {
long requestTimestampMs, long responseTimestampMs) {
if (Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 0) {
- if (DBG) log("Don't send network conditions - lacking user consent.");
return;
}
@@ -754,7 +768,7 @@ public class NetworkMonitor extends StateMachine {
if (cellInfo.isRegistered()) {
numRegisteredCellInfo++;
if (numRegisteredCellInfo > 1) {
- if (DBG) log("more than one registered CellInfo. Can't " +
+ log("more than one registered CellInfo. Can't " +
"tell which is active. Bailing.");
return;
}
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index e1ec8a6..2846185 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -1135,7 +1135,7 @@ public class Vpn {
final ConnectivityManager cm = ConnectivityManager.from(mContext);
for (Network network : cm.getAllNetworks()) {
final LinkProperties lp = cm.getLinkProperties(network);
- if (lp != null && mOuterInterface.equals(lp.getInterfaceName())) {
+ if (lp != null && lp.getAllInterfaceNames().contains(mOuterInterface)) {
final NetworkInfo networkInfo = cm.getNetworkInfo(network);
if (networkInfo != null) mOuterConnection.set(networkInfo.getType());
}
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 93ed2ee..c13401f 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -23,12 +23,15 @@ import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.IContentService;
+import android.content.Intent;
import android.content.ISyncStatusObserver;
import android.content.PeriodicSync;
import android.content.SyncAdapterType;
import android.content.SyncInfo;
import android.content.SyncRequest;
import android.content.SyncStatusInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.database.IContentObserver;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
@@ -44,6 +47,7 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
import android.util.SparseIntArray;
+import com.android.server.LocalServices;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -151,6 +155,18 @@ public final class ContentService extends IContentService.Stub {
/*package*/ ContentService(Context context, boolean factoryTest) {
mContext = context;
mFactoryTest = factoryTest;
+
+ // Let the package manager query for the sync adapters for a given authority
+ // as we grant default permissions to sync adapters for specifix authorities.
+ PackageManagerInternal packageManagerInternal = LocalServices.getService(
+ PackageManagerInternal.class);
+ packageManagerInternal.setSyncAdapterPackagesprovider(
+ new PackageManagerInternal.SyncAdapterPackagesProvider() {
+ @Override
+ public String[] getPackages(String authority, int userId) {
+ return getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
+ }
+ });
}
public void systemReady() {
@@ -161,8 +177,9 @@ public final class ContentService extends IContentService.Stub {
* Register a content observer tied to a specific user's view of the provider.
* @param userHandle the user whose view of the provider is to be observed. May be
* the calling user without requiring any permission, otherwise the caller needs to
- * hold the INTERACT_ACROSS_USERS_FULL permission. Pseudousers USER_ALL and
- * USER_CURRENT are properly handled; all other pseudousers are forbidden.
+ * hold the INTERACT_ACROSS_USERS_FULL permission or hold a read uri grant to the uri.
+ * Pseudousers USER_ALL and USER_CURRENT are properly handled; all other pseudousers
+ * are forbidden.
*/
@Override
public void registerContentObserver(Uri uri, boolean notifyForDescendants,
@@ -171,8 +188,17 @@ public final class ContentService extends IContentService.Stub {
throw new IllegalArgumentException("You must pass a valid uri and observer");
}
- enforceCrossUserPermission(userHandle,
- "no permission to observe other users' provider view");
+ final int uid = Binder.getCallingUid();
+ final int pid = Binder.getCallingPid();
+ final int callingUserHandle = UserHandle.getCallingUserId();
+ // Registering an observer for any user other than the calling user requires uri grant or
+ // cross user permission
+ if (callingUserHandle != userHandle &&
+ mContext.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ != PackageManager.PERMISSION_GRANTED) {
+ enforceCrossUserPermission(userHandle,
+ "no permission to observe other users' provider view");
+ }
if (userHandle < 0) {
if (userHandle == UserHandle.USER_CURRENT) {
@@ -185,7 +211,7 @@ public final class ContentService extends IContentService.Stub {
synchronized (mRootNode) {
mRootNode.addObserverLocked(uri, observer, notifyForDescendants, mRootNode,
- Binder.getCallingUid(), Binder.getCallingPid(), userHandle);
+ uid, pid, userHandle);
if (false) Log.v(TAG, "Registered observer " + observer + " at " + uri +
" with notifyForDescendants " + notifyForDescendants);
}
@@ -211,8 +237,9 @@ public final class ContentService extends IContentService.Stub {
* Notify observers of a particular user's view of the provider.
* @param userHandle the user whose view of the provider is to be notified. May be
* the calling user without requiring any permission, otherwise the caller needs to
- * hold the INTERACT_ACROSS_USERS_FULL permission. Pseudousers USER_ALL and
- * USER_CURRENT are properly interpreted; no other pseudousers are allowed.
+ * hold the INTERACT_ACROSS_USERS_FULL permission or hold a write uri grant to the uri.
+ * Pseudousers USER_ALL and USER_CURRENT are properly interpreted; no other pseudousers are
+ * allowed.
*/
@Override
public void notifyChange(Uri uri, IContentObserver observer,
@@ -223,11 +250,14 @@ public final class ContentService extends IContentService.Stub {
+ " from observer " + observer + ", syncToNetwork " + syncToNetwork);
}
- // Notify for any user other than the caller's own requires permission.
+ final int uid = Binder.getCallingUid();
+ final int pid = Binder.getCallingPid();
final int callingUserHandle = UserHandle.getCallingUserId();
- if (userHandle != callingUserHandle) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS,
- "no permission to notify other users");
+ // Notify for any user other than the caller requires uri grant or cross user permission
+ if (callingUserHandle != userHandle &&
+ mContext.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
+ != PackageManager.PERMISSION_GRANTED) {
+ enforceCrossUserPermission(userHandle, "no permission to notify other users");
}
// We passed the permission check; resolve pseudouser targets as appropriate
@@ -240,7 +270,6 @@ public final class ContentService extends IContentService.Stub {
}
}
- final int uid = Binder.getCallingUid();
// This makes it so that future permission checks will be in the context of this
// process rather than the caller's process. We will restore this before returning.
long identityToken = clearCallingIdentity();
diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java
index cff4814..8105675 100644
--- a/services/core/java/com/android/server/dreams/DreamController.java
+++ b/services/core/java/com/android/server/dreams/DreamController.java
@@ -16,6 +16,8 @@
package com.android.server.dreams;
+import com.android.internal.logging.MetricsLogger;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -25,6 +27,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.IBinder.DeathRecipient;
+import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
import android.service.dreams.DreamService;
@@ -55,6 +58,7 @@ final class DreamController {
private final Handler mHandler;
private final Listener mListener;
private final IWindowManager mIWindowManager;
+ private long mDreamStartTime;
private final Intent mDreamingStartedIntent = new Intent(Intent.ACTION_DREAMING_STARTED)
.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
@@ -123,6 +127,10 @@ final class DreamController {
mCurrentDream = new DreamRecord(token, name, isTest, canDoze, userId);
+ mDreamStartTime = SystemClock.elapsedRealtime();
+ MetricsLogger.visible(mContext,
+ mCurrentDream.mCanDoze ? MetricsLogger.DOZING : MetricsLogger.DREAMING);
+
try {
mIWindowManager.addWindowToken(token, WindowManager.LayoutParams.TYPE_DREAM);
} catch (RemoteException ex) {
@@ -185,6 +193,11 @@ final class DreamController {
Slog.i(TAG, "Stopping dream: name=" + oldDream.mName
+ ", isTest=" + oldDream.mIsTest + ", canDoze=" + oldDream.mCanDoze
+ ", userId=" + oldDream.mUserId);
+ MetricsLogger.hidden(mContext,
+ oldDream.mCanDoze ? MetricsLogger.DOZING : MetricsLogger.DREAMING);
+ MetricsLogger.histogram(mContext,
+ oldDream.mCanDoze ? "dozing_minutes" : "dreaming_minutes" ,
+ (int) ((SystemClock.elapsedRealtime() - mDreamStartTime) / (1000L * 60L)));
mHandler.removeCallbacks(mStopUnconnectedDreamRunnable);
mHandler.removeCallbacks(mStopStubbornDreamRunnable);
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index c52a1c1..9ee3bc2 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -30,9 +30,11 @@ import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.Looper;
import android.os.MessageQueue;
+import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SELinux;
import android.os.ServiceManager;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Slog;
@@ -70,6 +72,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
private static final int MSG_USER_SWITCHING = 10;
private static final int ENROLLMENT_TIMEOUT_MS = 60 * 1000; // 1 minute
+ private boolean mIsKeyguard; // true if the authentication client is keyguard
private ClientMonitor mAuthClient = null;
private ClientMonitor mEnrollClient = null;
private ClientMonitor mRemoveClient = null;
@@ -78,6 +81,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
private static final long MS_PER_SEC = 1000;
private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30*1000;
private static final int MAX_FAILED_ATTEMPTS = 5;
+ private static final int FINGERPRINT_ACQUIRED_GOOD = 0;
Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
@@ -97,6 +101,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
private long mHalDeviceId;
private int mFailedAttempts;
private IFingerprintDaemon mDaemon;
+ private PowerManager mPowerManager;
private final Runnable mLockoutReset = new Runnable() {
@Override
@@ -109,6 +114,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
super(context);
mContext = context;
mAppOps = context.getSystemService(AppOpsManager.class);
+ mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
}
@Override
@@ -191,7 +197,11 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
removeClient(mAuthClient);
}
}
+ }
+ private void userActivity() {
+ long now = SystemClock.uptimeMillis();
+ mPowerManager.userActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
}
void handleUserSwitching(int userId) {
@@ -498,9 +508,10 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
*/
private boolean sendAuthenticated(int fpId, int groupId) {
boolean result = false;
+ boolean authenticated = fpId != 0;
if (receiver != null) {
try {
- if (fpId == 0) {
+ if (!authenticated) {
receiver.onAuthenticationFailed(mHalDeviceId);
} else {
Fingerprint fp = !restricted ?
@@ -522,6 +533,11 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
result |= true; // we have a valid fingerprint
mLockoutReset.run();
}
+ // For fingerprint devices that support touch-to-wake, this will ensure the device
+ // wakes up and turns the screen on when fingerprint is authenticated.
+ if (mIsKeyguard && authenticated) {
+ mPowerManager.wakeUp(SystemClock.uptimeMillis());
+ }
return result;
}
@@ -537,6 +553,12 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
Slog.w(TAG, "Failed to invoke sendAcquired:", e);
return true; // client failed
}
+ finally {
+ // Good scans will keep the device awake
+ if (acquiredInfo == FINGERPRINT_ACQUIRED_GOOD) {
+ userActivity();
+ }
+ }
}
/*
@@ -589,6 +611,8 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
};
private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
+ private static final String KEYGUARD_PACKAGE = "com.android.systemui";
+
@Override // Binder call
public long preEnroll(IBinder token) {
checkPermission(MANAGE_FINGERPRINT);
@@ -638,7 +662,8 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
@Override // Binder call
public void authenticate(final IBinder token, final long opId, final int groupId,
- final IFingerprintServiceReceiver receiver, final int flags, String opPackageName) {
+ final IFingerprintServiceReceiver receiver, final int flags,
+ final String opPackageName) {
if (!canUseFingerprint(opPackageName)) {
return;
@@ -647,6 +672,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
mHandler.post(new Runnable() {
@Override
public void run() {
+ mIsKeyguard = KEYGUARD_PACKAGE.equals(opPackageName);
startAuthentication(token, opId, groupId, receiver, flags, restricted);
}
});
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 3850306..45a4829 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -281,8 +281,16 @@ public class GpsLocationProvider implements LocationProviderInterface {
// current setting 24 hours
private static final long NTP_INTERVAL = 24*60*60*1000;
// how long to wait if we have a network error in NTP or XTRA downloading
+ // the initial value of the exponential backoff
// current setting - 5 minutes
private static final long RETRY_INTERVAL = 5*60*1000;
+ // how long to wait if we have a network error in NTP or XTRA downloading
+ // the max value of the exponential backoff
+ // current setting - 4 hours
+ private static final long MAX_RETRY_INTERVAL = 4*60*60*1000;
+
+ private BackOff mNtpBackOff = new BackOff(RETRY_INTERVAL, MAX_RETRY_INTERVAL);
+ private BackOff mXtraBackOff = new BackOff(RETRY_INTERVAL, MAX_RETRY_INTERVAL);
// true if we are enabled, protected by this
private boolean mEnabled;
@@ -832,9 +840,10 @@ public class GpsLocationProvider implements LocationProviderInterface {
native_inject_time(time, timeReference, (int) certainty);
delay = NTP_INTERVAL;
+ mNtpBackOff.reset();
} else {
if (DEBUG) Log.d(TAG, "requestTime failed");
- delay = RETRY_INTERVAL;
+ delay = mNtpBackOff.nextBackoffMillis();
}
sendMessage(INJECT_NTP_TIME_FINISHED, 0, null);
@@ -875,6 +884,7 @@ public class GpsLocationProvider implements LocationProviderInterface {
Log.d(TAG, "calling native_inject_xtra_data");
}
native_inject_xtra_data(data, data.length);
+ mXtraBackOff.reset();
}
sendMessage(DOWNLOAD_XTRA_DATA_FINISHED, 0, null);
@@ -882,7 +892,8 @@ public class GpsLocationProvider implements LocationProviderInterface {
if (data == null) {
// try again later
// since this is delayed and not urgent we do not hold a wake lock here
- mHandler.sendEmptyMessageDelayed(DOWNLOAD_XTRA_DATA, RETRY_INTERVAL);
+ mHandler.sendEmptyMessageDelayed(DOWNLOAD_XTRA_DATA,
+ mXtraBackOff.nextBackoffMillis());
}
// release wake lock held by task
@@ -2190,6 +2201,36 @@ public class GpsLocationProvider implements LocationProviderInterface {
pw.append(s);
}
+ /**
+ * A simple implementation of exponential backoff.
+ */
+ private static final class BackOff {
+ private static final int MULTIPLIER = 2;
+ private final long mInitIntervalMillis;
+ private final long mMaxIntervalMillis;
+ private long mCurrentIntervalMillis;
+
+ public BackOff(long initIntervalMillis, long maxIntervalMillis) {
+ mInitIntervalMillis = initIntervalMillis;
+ mMaxIntervalMillis = maxIntervalMillis;
+
+ mCurrentIntervalMillis = mInitIntervalMillis / MULTIPLIER;
+ }
+
+ public long nextBackoffMillis() {
+ if (mCurrentIntervalMillis > mMaxIntervalMillis) {
+ return mMaxIntervalMillis;
+ }
+
+ mCurrentIntervalMillis *= MULTIPLIER;
+ return mCurrentIntervalMillis;
+ }
+
+ public void reset() {
+ mCurrentIntervalMillis = mInitIntervalMillis / MULTIPLIER;
+ }
+ }
+
// for GPS SV statistics
private static final int MAX_SVS = 32;
private static final int EPHEMERIS_MASK = 0;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 847bcb5..f618c3e 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -146,6 +146,7 @@ import android.util.SparseIntArray;
import android.util.TrustedTime;
import android.util.Xml;
+import com.android.server.EventLogTags;
import libcore.io.IoUtils;
import com.android.internal.R;
@@ -1764,7 +1765,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
if (mDeviceIdleMode != enabled) {
mDeviceIdleMode = enabled;
if (mSystemReady) {
- updateRulesForGlobalChangeLocked(true);
+ updateRulesForDeviceIdleLocked();
+ }
+ if (enabled) {
+ EventLogTags.writeDeviceIdleOnPhase("net");
+ } else {
+ EventLogTags.writeDeviceIdleOffPhase("net");
}
}
}
@@ -2093,8 +2099,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
for (UserInfo user : users) {
for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) {
int appId = mPowerSaveTempWhitelistAppIds.keyAt(i);
+ boolean isAllow = mPowerSaveTempWhitelistAppIds.valueAt(i);
int uid = UserHandle.getUid(user.id, appId);
updateRulesForUidLocked(uid);
+ setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, !isAllow);
}
}
}
@@ -2190,11 +2198,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final boolean firewallReject = (uidRules & RULE_REJECT_ALL) != 0;
if (oldFirewallReject != firewallReject) {
setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, firewallReject);
- if (mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE) && !firewallReject) {
- // if the dozable chain is on, and we decide to allow this uid. we need to punch
- // a hole in the dozable chain.
- setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, false);
- }
}
// dispatch changed rule to existing listeners
diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java
index 87b4f8c..6a1401c 100644
--- a/services/core/java/com/android/server/notification/NotificationDelegate.java
+++ b/services/core/java/com/android/server/notification/NotificationDelegate.java
@@ -28,7 +28,7 @@ public interface NotificationDelegate {
void onNotificationError(int callingUid, int callingPid,
String pkg, String tag, int id,
int uid, int initialPid, String message, int userId);
- void onPanelRevealed(boolean clearEffects);
+ void onPanelRevealed(boolean clearEffects, int numItems);
void onPanelHidden();
void clearEffects();
void onNotificationVisibilityChanged(
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d6a7bf93..87e9d42 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -567,8 +567,8 @@ public class NotificationManagerService extends SystemService {
}
@Override
- public void onPanelRevealed(boolean clearEffects) {
- EventLogTags.writeNotificationPanelRevealed();
+ public void onPanelRevealed(boolean clearEffects, int items) {
+ EventLogTags.writeNotificationPanelRevealed(items);
if (clearEffects) {
clearEffects();
}
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 3ea384c..e459e26 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -17,15 +17,21 @@
package com.android.server.pm;
import android.Manifest;
+import android.app.DownloadManager;
+import android.app.admin.DevicePolicyManager;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal.PackagesProvider;
+import android.content.pm.PackageManagerInternal.SyncAdapterPackagesProvider;
import android.content.pm.PackageParser;
+import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.os.UserHandle;
+import android.provider.CalendarContract;
+import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.util.ArraySet;
import android.util.Log;
@@ -49,12 +55,13 @@ final class DefaultPermissionGrantPolicy {
private static final boolean DEBUG = false;
private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
+ private static final String AUDIO_MIME_TYPE = "audio/mpeg";
private static final Set<String> PHONE_PERMISSIONS = new ArraySet<>();
static {
PHONE_PERMISSIONS.add(Manifest.permission.READ_PHONE_STATE);
PHONE_PERMISSIONS.add(Manifest.permission.CALL_PHONE);
- PHONE_PERMISSIONS.add( Manifest.permission.READ_CALL_LOG);
+ PHONE_PERMISSIONS.add(Manifest.permission.READ_CALL_LOG);
PHONE_PERMISSIONS.add(Manifest.permission.WRITE_CALL_LOG);
PHONE_PERMISSIONS.add(Manifest.permission.ADD_VOICEMAIL);
PHONE_PERMISSIONS.add(Manifest.permission.USE_SIP);
@@ -110,6 +117,11 @@ final class DefaultPermissionGrantPolicy {
STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
+ private static final Set<String> ACCOUNTS_PERMISSIONS = new ArraySet<>();
+ static {
+ //ACCOUNTS_PERMISSIONS.add(Manifest.permission.GET_ACCOUNTS);
+ }
+
private static final Set<String> SETTINGS_PERMISSIONS = new ArraySet<>();
static {
SETTINGS_PERMISSIONS.add(Manifest.permission.WRITE_SETTINGS);
@@ -133,7 +145,9 @@ final class DefaultPermissionGrantPolicy {
private PackagesProvider mImePackagesProvider;
private PackagesProvider mLocationPackagesProvider;
private PackagesProvider mVoiceInteractionPackagesProvider;
- private PackagesProvider mCarrierAppPackagesProvider;
+ private PackagesProvider mSmsAppPackagesProvider;
+ private PackagesProvider mDialerAppPackagesProvider;
+ private SyncAdapterPackagesProvider mSyncAdapterPackagesProvider;
public DefaultPermissionGrantPolicy(PackageManagerService service) {
mService = service;
@@ -151,8 +165,16 @@ final class DefaultPermissionGrantPolicy {
mVoiceInteractionPackagesProvider = provider;
}
- public void setCarrierAppPackagesProviderLPw(PackagesProvider provider) {
- mCarrierAppPackagesProvider = provider;
+ public void setSmsAppPackagesProviderLPw(PackagesProvider provider) {
+ mSmsAppPackagesProvider = provider;
+ }
+
+ public void setDialerAppPackagesProviderLPw(PackagesProvider provider) {
+ mDialerAppPackagesProvider = provider;
+ }
+
+ public void setSyncAdapterPackagesProviderrLPw(SyncAdapterPackagesProvider provider) {
+ mSyncAdapterPackagesProvider = provider;
}
public void grantDefaultPermissions(int userId) {
@@ -161,7 +183,7 @@ final class DefaultPermissionGrantPolicy {
}
private void grantPermissionsToSysComponentsAndPrivApps(int userId) {
- Log.i(TAG, "Granting permissions to platform components");
+ Log.i(TAG, "Granting permissions to platform components for user " + userId);
synchronized (mService.mPackages) {
for (PackageParser.Package pkg : mService.mPackages.values()) {
@@ -193,18 +215,22 @@ final class DefaultPermissionGrantPolicy {
}
private void grantDefaultSystemHandlerPermissions(int userId) {
- Log.i(TAG, "Granting permissions to default platform handlers");
+ Log.i(TAG, "Granting permissions to default platform handlers for user " + userId);
final PackagesProvider imePackagesProvider;
final PackagesProvider locationPackagesProvider;
final PackagesProvider voiceInteractionPackagesProvider;
- final PackagesProvider carrierAppPackagesProvider;
+ final PackagesProvider smsAppPackagesProvider;
+ final PackagesProvider dialerAppPackagesProvider;
+ final SyncAdapterPackagesProvider syncAdapterPackagesProvider;
synchronized (mService.mPackages) {
imePackagesProvider = mImePackagesProvider;
locationPackagesProvider = mLocationPackagesProvider;
voiceInteractionPackagesProvider = mVoiceInteractionPackagesProvider;
- carrierAppPackagesProvider = mCarrierAppPackagesProvider;
+ smsAppPackagesProvider = mSmsAppPackagesProvider;
+ dialerAppPackagesProvider = mDialerAppPackagesProvider;
+ syncAdapterPackagesProvider = mSyncAdapterPackagesProvider;
}
String[] imePackageNames = (imePackagesProvider != null)
@@ -213,8 +239,14 @@ final class DefaultPermissionGrantPolicy {
? voiceInteractionPackagesProvider.getPackages(userId) : null;
String[] locationPackageNames = (locationPackagesProvider != null)
? locationPackagesProvider.getPackages(userId) : null;
- String[] carrierAppPackageNames = (carrierAppPackagesProvider != null)
- ? carrierAppPackagesProvider.getPackages(userId) : null;
+ String[] smsAppPackageNames = (smsAppPackagesProvider != null)
+ ? smsAppPackagesProvider.getPackages(userId) : null;
+ String[] dialerAppPackageNames = (dialerAppPackagesProvider != null)
+ ? dialerAppPackagesProvider.getPackages(userId) : null;
+ String[] contactsSyncAdapterPackages = (syncAdapterPackagesProvider != null) ?
+ syncAdapterPackagesProvider.getPackages(ContactsContract.AUTHORITY, userId) : null;
+ String[] calendarSyncAdapterPackages = (syncAdapterPackagesProvider != null) ?
+ syncAdapterPackagesProvider.getPackages(CalendarContract.AUTHORITY, userId) : null;
synchronized (mService.mPackages) {
// Installers
@@ -228,6 +260,7 @@ final class DefaultPermissionGrantPolicy {
for (int i = 0; i < installerCount; i++) {
PackageParser.Package installPackage = installerPackages.get(i);
grantInstallPermissionsLPw(installPackage, INSTALLER_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(installPackage, STORAGE_PERMISSIONS, true, userId);
}
// Verifiers
@@ -239,12 +272,13 @@ final class DefaultPermissionGrantPolicy {
for (int i = 0; i < verifierCount; i++) {
PackageParser.Package verifierPackage = verifierPackages.get(i);
grantInstallPermissionsLPw(verifierPackage, VERIFIER_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(verifierPackage, STORAGE_PERMISSIONS, userId);
}
// SetupWizard
Intent setupIntent = new Intent(Intent.ACTION_MAIN);
setupIntent.addCategory(Intent.CATEGORY_HOME);
- PackageParser.Package setupPackage = getDefaultSystemHandlerActvityPackageLPr(
+ PackageParser.Package setupPackage = getDefaultSystemHandlerActivityPackageLPr(
setupIntent, userId);
if (setupPackage != null
&& doesPackageSupportRuntimePermissions(setupPackage)) {
@@ -253,76 +287,185 @@ final class DefaultPermissionGrantPolicy {
grantRuntimePermissionsLPw(setupPackage, SETTINGS_PERMISSIONS, userId);
}
- // Phone
- Intent dialerIntent = new Intent(Intent.ACTION_DIAL);
- PackageParser.Package dialerPackage = getDefaultSystemHandlerActvityPackageLPr(
- dialerIntent, userId);
- if (dialerPackage != null
- && doesPackageSupportRuntimePermissions(dialerPackage)) {
- grantRuntimePermissionsLPw(dialerPackage, PHONE_PERMISSIONS, userId);
- grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId);
- grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, userId);
- grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, userId);
- }
-
// Camera
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- PackageParser.Package cameraPackage = getDefaultSystemHandlerActvityPackageLPr(
+ PackageParser.Package cameraPackage = getDefaultSystemHandlerActivityPackageLPr(
cameraIntent, userId);
if (cameraPackage != null
&& doesPackageSupportRuntimePermissions(cameraPackage)) {
grantRuntimePermissionsLPw(cameraPackage, CAMERA_PERMISSIONS, userId);
grantRuntimePermissionsLPw(cameraPackage, MICROPHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(cameraPackage, STORAGE_PERMISSIONS, userId);
}
- // Messaging
- Intent messagingIntent = new Intent(Intent.ACTION_MAIN);
- messagingIntent.addCategory(Intent.CATEGORY_APP_MESSAGING);
- PackageParser.Package messagingPackage = getDefaultSystemHandlerActvityPackageLPr(
- messagingIntent, userId);
- if (messagingPackage != null
- && doesPackageSupportRuntimePermissions(messagingPackage)) {
- grantRuntimePermissionsLPw(messagingPackage, PHONE_PERMISSIONS, userId);
- grantRuntimePermissionsLPw(messagingPackage, CONTACTS_PERMISSIONS, userId);
- grantRuntimePermissionsLPw(messagingPackage, SMS_PERMISSIONS, userId);
+ // Media provider
+ PackageParser.Package mediaStorePackage = getDefaultProviderAuthorityPackageLPr(
+ MediaStore.AUTHORITY, userId);
+ if (mediaStorePackage != null) {
+ grantRuntimePermissionsLPw(mediaStorePackage, STORAGE_PERMISSIONS, true, userId);
+ }
+
+ // Downloads provider
+ PackageParser.Package downloadsPackage = getDefaultProviderAuthorityPackageLPr(
+ "downloads", userId);
+ if (downloadsPackage != null) {
+ grantRuntimePermissionsLPw(downloadsPackage, STORAGE_PERMISSIONS, true, userId);
+ }
+
+ // Downloads UI
+ Intent downloadsUiIntent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
+ PackageParser.Package downloadsUiPackage = getDefaultSystemHandlerActivityPackageLPr(
+ downloadsUiIntent, userId);
+ if (downloadsUiPackage != null
+ && doesPackageSupportRuntimePermissions(downloadsUiPackage)) {
+ grantRuntimePermissionsLPw(downloadsUiPackage, STORAGE_PERMISSIONS, true, userId);
+ }
+
+ // Storage provider
+ PackageParser.Package storagePackage = getDefaultProviderAuthorityPackageLPr(
+ "com.android.externalstorage.documents", userId);
+ if (storagePackage != null) {
+ grantRuntimePermissionsLPw(storagePackage, STORAGE_PERMISSIONS, userId);
+ }
+
+ // Dialer
+ if (dialerAppPackageNames == null) {
+ Intent dialerIntent = new Intent(Intent.ACTION_DIAL);
+ PackageParser.Package dialerPackage = getDefaultSystemHandlerActivityPackageLPr(
+ dialerIntent, userId);
+ if (dialerPackage != null) {
+ grantDefaultPermissionsToDefaultSystemDialerAppLPr(dialerPackage, userId);
+ }
+ } else {
+ for (String dialerAppPackageName : dialerAppPackageNames) {
+ PackageParser.Package dialerPackage = getSystemPackageLPr(dialerAppPackageName);
+ if (dialerPackage != null) {
+ grantDefaultPermissionsToDefaultSystemDialerAppLPr(dialerPackage, userId);
+ }
+ }
+ }
+
+ // SMS
+ if (smsAppPackageNames == null) {
+ Intent smsIntent = new Intent(Intent.ACTION_MAIN);
+ smsIntent.addCategory(Intent.CATEGORY_APP_MESSAGING);
+ PackageParser.Package smsPackage = getDefaultSystemHandlerActivityPackageLPr(
+ smsIntent, userId);
+ if (smsPackage != null) {
+ grantDefaultPermissionsToDefaultSystemSmsAppLPr(smsPackage, userId);
+ }
+ } else {
+ for (String smsPackageName : smsAppPackageNames) {
+ PackageParser.Package smsPackage = getSystemPackageLPr(smsPackageName);
+ if (smsPackage != null) {
+ grantDefaultPermissionsToDefaultSystemSmsAppLPr(smsPackage, userId);
+ }
+ }
}
// Calendar
Intent calendarIntent = new Intent(Intent.ACTION_MAIN);
calendarIntent.addCategory(Intent.CATEGORY_APP_CALENDAR);
- PackageParser.Package calendarPackage = getDefaultSystemHandlerActvityPackageLPr(
+ PackageParser.Package calendarPackage = getDefaultSystemHandlerActivityPackageLPr(
calendarIntent, userId);
if (calendarPackage != null
&& doesPackageSupportRuntimePermissions(calendarPackage)) {
grantRuntimePermissionsLPw(calendarPackage, CALENDAR_PERMISSIONS, userId);
grantRuntimePermissionsLPw(calendarPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(calendarPackage, ACCOUNTS_PERMISSIONS, userId);
+ }
+
+ // Calendar provider
+ PackageParser.Package calendarProviderPackage = getDefaultProviderAuthorityPackageLPr(
+ CalendarContract.AUTHORITY, userId);
+ if (calendarProviderPackage != null) {
+ grantRuntimePermissionsLPw(calendarProviderPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(calendarProviderPackage, CALENDAR_PERMISSIONS,
+ true, userId);
+ grantRuntimePermissionsLPw(calendarProviderPackage, ACCOUNTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(calendarProviderPackage, STORAGE_PERMISSIONS, userId);
+ }
+
+ // Calendar provider sync adapters
+ List<PackageParser.Package> calendarSyncAdapters = getHeadlessSyncAdapterPackagesLPr(
+ calendarSyncAdapterPackages,
+ userId);
+ final int calendarSyncAdapterCount = calendarSyncAdapters.size();
+ for (int i = 0; i < calendarSyncAdapterCount; i++) {
+ PackageParser.Package calendarSyncAdapter = calendarSyncAdapters.get(i);
+ if (doesPackageSupportRuntimePermissions(calendarSyncAdapter)) {
+ grantRuntimePermissionsLPw(calendarSyncAdapter, CALENDAR_PERMISSIONS, userId);
+ }
}
// Contacts
Intent contactsIntent = new Intent(Intent.ACTION_MAIN);
contactsIntent.addCategory(Intent.CATEGORY_APP_CONTACTS);
- PackageParser.Package contactsPackage = getDefaultSystemHandlerActvityPackageLPr(
+ PackageParser.Package contactsPackage = getDefaultSystemHandlerActivityPackageLPr(
contactsIntent, userId);
if (contactsPackage != null
&& doesPackageSupportRuntimePermissions(contactsPackage)) {
grantRuntimePermissionsLPw(contactsPackage, CONTACTS_PERMISSIONS, userId);
grantRuntimePermissionsLPw(contactsPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(contactsPackage, ACCOUNTS_PERMISSIONS, userId);
+ }
+
+ // Contacts provider sync adapters
+ List<PackageParser.Package> contactsSyncAdapters = getHeadlessSyncAdapterPackagesLPr(
+ contactsSyncAdapterPackages,
+ userId);
+ final int contactsSyncAdapterCount = contactsSyncAdapters.size();
+ for (int i = 0; i < contactsSyncAdapterCount; i++) {
+ PackageParser.Package contactsSyncAdapter = contactsSyncAdapters.get(i);
+ if (doesPackageSupportRuntimePermissions(contactsSyncAdapter)) {
+ grantRuntimePermissionsLPw(contactsSyncAdapter, CONTACTS_PERMISSIONS, userId);
+ }
+ }
+
+ // Contacts provider
+ PackageParser.Package contactsProviderPackage = getDefaultProviderAuthorityPackageLPr(
+ ContactsContract.AUTHORITY, userId);
+ if (contactsProviderPackage != null) {
+ grantRuntimePermissionsLPw(contactsProviderPackage, CONTACTS_PERMISSIONS,
+ true, userId);
+ grantRuntimePermissionsLPw(contactsProviderPackage, ACCOUNTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(contactsProviderPackage, STORAGE_PERMISSIONS, userId);
+ }
+
+ // Device provisioning
+ Intent deviceProvisionIntent = new Intent(
+ DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE);
+ PackageParser.Package deviceProvisionPackage =
+ getDefaultSystemHandlerActivityPackageLPr(deviceProvisionIntent, userId);
+ if (deviceProvisionPackage != null
+ && doesPackageSupportRuntimePermissions(deviceProvisionPackage)) {
+ grantRuntimePermissionsLPw(contactsPackage, ACCOUNTS_PERMISSIONS, userId);
}
// Maps
Intent mapsIntent = new Intent(Intent.ACTION_MAIN);
mapsIntent.addCategory(Intent.CATEGORY_APP_MAPS);
- PackageParser.Package mapsPackage = getDefaultSystemHandlerActvityPackageLPr(
+ PackageParser.Package mapsPackage = getDefaultSystemHandlerActivityPackageLPr(
mapsIntent, userId);
if (mapsPackage != null
&& doesPackageSupportRuntimePermissions(mapsPackage)) {
grantRuntimePermissionsLPw(mapsPackage, LOCATION_PERMISSIONS, userId);
}
+ // Gallery
+ Intent galleryIntent = new Intent(Intent.ACTION_MAIN);
+ galleryIntent.addCategory(Intent.CATEGORY_APP_GALLERY);
+ PackageParser.Package galleryPackage = getDefaultSystemHandlerActivityPackageLPr(
+ galleryIntent, userId);
+ if (galleryPackage != null
+ && doesPackageSupportRuntimePermissions(galleryPackage)) {
+ grantRuntimePermissionsLPw(galleryPackage, STORAGE_PERMISSIONS, userId);
+ }
+
// Email
Intent emailIntent = new Intent(Intent.ACTION_MAIN);
emailIntent.addCategory(Intent.CATEGORY_APP_EMAIL);
- PackageParser.Package emailPackage = getDefaultSystemHandlerActvityPackageLPr(
+ PackageParser.Package emailPackage = getDefaultSystemHandlerActivityPackageLPr(
emailIntent, userId);
if (emailPackage != null
&& doesPackageSupportRuntimePermissions(emailPackage)) {
@@ -330,10 +473,17 @@ final class DefaultPermissionGrantPolicy {
}
// Browser
- Intent browserIntent = new Intent(Intent.ACTION_MAIN);
- browserIntent.addCategory(Intent.CATEGORY_APP_BROWSER);
- PackageParser.Package browserPackage = getDefaultSystemHandlerActvityPackageLPr(
- browserIntent, userId);
+ PackageParser.Package browserPackage = null;
+ String defaultBrowserPackage = mService.getDefaultBrowserPackageName(userId);
+ if (defaultBrowserPackage != null) {
+ browserPackage = getPackageLPr(defaultBrowserPackage);
+ }
+ if (browserPackage == null) {
+ Intent browserIntent = new Intent(Intent.ACTION_MAIN);
+ browserIntent.addCategory(Intent.CATEGORY_APP_BROWSER);
+ browserPackage = getDefaultSystemHandlerActivityPackageLPr(
+ browserIntent, userId);
+ }
if (browserPackage != null
&& doesPackageSupportRuntimePermissions(browserPackage)) {
grantRuntimePermissionsLPw(browserPackage, LOCATION_PERMISSIONS, userId);
@@ -384,7 +534,8 @@ final class DefaultPermissionGrantPolicy {
grantRuntimePermissionsLPw(locationPackage, MICROPHONE_PERMISSIONS, userId);
grantRuntimePermissionsLPw(locationPackage, PHONE_PERMISSIONS, userId);
grantRuntimePermissionsLPw(locationPackage, SMS_PERMISSIONS, userId);
- grantRuntimePermissionsLPw(locationPackage, LOCATION_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, LOCATION_PERMISSIONS,
+ true, userId);
grantRuntimePermissionsLPw(locationPackage, CAMERA_PERMISSIONS, userId);
grantRuntimePermissionsLPw(locationPackage, SENSORS_PERMISSIONS, userId);
grantRuntimePermissionsLPw(locationPackage, STORAGE_PERMISSIONS, userId);
@@ -392,20 +543,98 @@ final class DefaultPermissionGrantPolicy {
}
}
- // Carrier apps
- if (carrierAppPackageNames != null) {
- for (String packageName : carrierAppPackageNames) {
- PackageParser.Package carrierPackage = getSystemPackageLPr(packageName);
- if (carrierPackage != null
- && doesPackageSupportRuntimePermissions(carrierPackage)) {
- grantRuntimePermissionsLPw(carrierPackage, PHONE_PERMISSIONS, userId);
- grantRuntimePermissionsLPw(carrierPackage, LOCATION_PERMISSIONS, userId);
- }
- }
+ // Music
+ Intent musicIntent = new Intent(Intent.ACTION_VIEW);
+ musicIntent.addCategory(Intent.CATEGORY_DEFAULT);
+ musicIntent.setDataAndType(Uri.fromFile(new File("foo.mp3")),
+ AUDIO_MIME_TYPE);
+ PackageParser.Package musicPackage = getDefaultSystemHandlerActivityPackageLPr(
+ musicIntent, userId);
+ if (musicPackage != null
+ && doesPackageSupportRuntimePermissions(musicPackage)) {
+ grantRuntimePermissionsLPw(musicPackage, STORAGE_PERMISSIONS, userId);
+ }
+
+ mService.mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
+ }
+ }
+
+ private void grantDefaultPermissionsToDefaultSystemDialerAppLPr(
+ PackageParser.Package dialerPackage, int userId) {
+ if (doesPackageSupportRuntimePermissions(dialerPackage)) {
+ grantRuntimePermissionsLPw(dialerPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, userId);
+ }
+ }
+
+
+ private void grantDefaultPermissionsToDefaultSystemSmsAppLPr(
+ PackageParser.Package smsPackage, int userId) {
+ if (doesPackageSupportRuntimePermissions(smsPackage)) {
+ grantRuntimePermissionsLPw(smsPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(smsPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(smsPackage, SMS_PERMISSIONS, userId);
+ }
+ }
+
+
+ public void grantDefaultPermissionsToDefaultSmsAppLPr(String packageName, int userId) {
+ Log.i(TAG, "Granting permissions to default sms app for user:" + userId);
+ if (packageName == null) {
+ return;
+ }
+ PackageParser.Package smsPackage = getPackageLPr(packageName);
+ if (smsPackage != null && doesPackageSupportRuntimePermissions(smsPackage)) {
+ grantRuntimePermissionsLPw(smsPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(smsPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(smsPackage, SMS_PERMISSIONS, userId);
+ }
+ }
+
+ public void grantDefaultPermissionsToDefaultDialerAppLPr(String packageName, int userId) {
+ Log.i(TAG, "Granting permissions to default dialer app for user:" + userId);
+ if (packageName == null) {
+ return;
+ }
+ PackageParser.Package dialerPackage = getPackageLPr(packageName);
+ if (dialerPackage != null
+ && doesPackageSupportRuntimePermissions(dialerPackage)) {
+ grantRuntimePermissionsLPw(dialerPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, userId);
+ }
+ }
+
+ public void grantDefaultPermissionsToEnabledCarrierAppsLPr(String[] packageNames, int userId) {
+ Log.i(TAG, "Granting permissions to enabled carrier apps for user:" + userId);
+ if (packageNames == null) {
+ return;
+ }
+ for (String packageName : packageNames) {
+ PackageParser.Package carrierPackage = getSystemPackageLPr(packageName);
+ if (carrierPackage != null
+ && doesPackageSupportRuntimePermissions(carrierPackage)) {
+ grantRuntimePermissionsLPw(carrierPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(carrierPackage, LOCATION_PERMISSIONS, userId);
}
}
}
+ public void grantDefaultPermissionsToDefaultBrowserLPr(String packageName, int userId) {
+ Log.i(TAG, "Granting permissions to default browser for user:" + userId);
+ if (packageName == null) {
+ return;
+ }
+ PackageParser.Package browserPackage = getSystemPackageLPr(packageName);
+ if (browserPackage != null
+ && doesPackageSupportRuntimePermissions(browserPackage)) {
+ grantRuntimePermissionsLPw(browserPackage, LOCATION_PERMISSIONS, userId);
+ }
+ }
+
private List<PackageParser.Package> getPrivilegedHandlerReceiverPackagesLPr(
Intent intent, int userId) {
List<ResolveInfo> handlers = mService.queryIntentReceivers(
@@ -436,7 +665,7 @@ final class DefaultPermissionGrantPolicy {
return handlerPackages;
}
- private PackageParser.Package getDefaultSystemHandlerActvityPackageLPr(
+ private PackageParser.Package getDefaultSystemHandlerActivityPackageLPr(
Intent intent, int userId) {
List<ResolveInfo> handlers = mService.queryIntentActivities(intent, null, 0, userId);
final int handlerCount = handlers.size();
@@ -452,8 +681,46 @@ final class DefaultPermissionGrantPolicy {
return null;
}
+ private List<PackageParser.Package> getHeadlessSyncAdapterPackagesLPr(
+ String[] syncAdapterPackageNames, int userId) {
+ List<PackageParser.Package> syncAdapterPackages = new ArrayList<>();
+
+ Intent homeIntent = new Intent(Intent.ACTION_MAIN);
+ homeIntent.addCategory(Intent.CATEGORY_HOME);
+
+ for (String syncAdapterPackageName : syncAdapterPackageNames) {
+ homeIntent.setPackage(syncAdapterPackageName);
+
+ List<ResolveInfo> homeActivities = mService.queryIntentActivities(homeIntent,
+ homeIntent.resolveType(mService.mContext.getContentResolver()), 0, userId);
+ if (!homeActivities.isEmpty()) {
+ continue;
+ }
+
+ PackageParser.Package syncAdapterPackage = getSystemPackageLPr(syncAdapterPackageName);
+ if (syncAdapterPackage != null) {
+ syncAdapterPackages.add(syncAdapterPackage);
+ }
+ }
+
+ return syncAdapterPackages;
+ }
+
+ private PackageParser.Package getDefaultProviderAuthorityPackageLPr(
+ String authority, int userId) {
+ ProviderInfo provider = mService.resolveContentProvider(authority, 0, userId);
+ if (provider != null) {
+ return getSystemPackageLPr(provider.packageName);
+ }
+ return null;
+ }
+
+ private PackageParser.Package getPackageLPr(String packageName) {
+ return mService.mPackages.get(packageName);
+ }
+
private PackageParser.Package getSystemPackageLPr(String packageName) {
- PackageParser.Package pkg = mService.mPackages.get(packageName);
+ PackageParser.Package pkg = getPackageLPr(packageName);
if (pkg != null && pkg.isSystemApp()) {
return !isSysComponentOrPersistentPrivApp(pkg) ? pkg : null;
}
@@ -470,6 +737,12 @@ final class DefaultPermissionGrantPolicy {
private void grantRuntimePermissionsLPw(PackageParser.Package pkg, Set<String> permissions,
int userId) {
+ grantRuntimePermissionsLPw(pkg, permissions, false, userId);
+
+ }
+
+ private void grantRuntimePermissionsLPw(PackageParser.Package pkg, Set<String> permissions,
+ boolean systemFixed, int userId) {
List<String> requestedPermissions = pkg.requestedPermissions;
if (pkg.isUpdatedSystemApp()) {
@@ -494,6 +767,12 @@ final class DefaultPermissionGrantPolicy {
Log.i(TAG, "Granted " + permission + " to default handler "
+ pkg.packageName);
}
+
+ if (systemFixed) {
+ mService.updatePermissionFlags(permission, pkg.packageName,
+ PackageManager.FLAG_PERMISSION_SYSTEM_FIXED,
+ PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, userId);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index d787919..4582828 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -271,7 +271,8 @@ public class LauncherAppsService extends SystemService {
Intent launchIntent = new Intent(Intent.ACTION_MAIN);
launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
launchIntent.setSourceBounds(sourceBounds);
- launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
launchIntent.setPackage(component.getPackageName());
long ident = Binder.clearCallingIdentity();
@@ -470,4 +471,4 @@ public class LauncherAppsService extends SystemService {
}
}
}
-} \ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index be1afa8..305eb8e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -18,6 +18,7 @@ package com.android.server.pm;
import static android.Manifest.permission.GRANT_REVOKE_PERMISSIONS;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
+import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
@@ -54,6 +55,7 @@ import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.pm.PackageParser.isApkFile;
import static android.os.Process.PACKAGE_INFO_GID;
import static android.os.Process.SYSTEM_UID;
@@ -100,7 +102,6 @@ import android.content.pm.IPackageInstaller;
import android.content.pm.IPackageManager;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
-import android.content.pm.IPackagesProvider;
import android.content.pm.InstrumentationInfo;
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.KeySet;
@@ -196,6 +197,7 @@ import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.content.PackageHelper;
import com.android.internal.os.IParcelFileDescriptorFactory;
import com.android.internal.os.SomeArgs;
+import com.android.internal.os.Zygote;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FastXmlSerializer;
@@ -208,8 +210,8 @@ import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemConfig;
import com.android.server.Watchdog;
-import com.android.server.pm.Settings.DatabaseVersion;
import com.android.server.pm.PermissionsState.PermissionState;
+import com.android.server.pm.Settings.DatabaseVersion;
import com.android.server.storage.DeviceStorageMonitorInternal;
import org.xmlpull.v1.XmlPullParser;
@@ -386,6 +388,15 @@ public class PackageManagerService extends IPackageManager.Stub {
/** Permission grant: grant as runtime a permission that was granted as an install time one. */
private static final int GRANT_UPGRADE = 5;
+ /** Canonical intent used to identify what counts as a "web browser" app */
+ private static final Intent sBrowserIntent;
+ static {
+ sBrowserIntent = new Intent();
+ sBrowserIntent.setAction(Intent.ACTION_VIEW);
+ sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
+ sBrowserIntent.setData(Uri.parse("http:"));
+ }
+
final ServiceThread mHandlerThread;
final PackageHandler mHandler;
@@ -1298,6 +1309,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (data != null) {
InstallArgs args = data.args;
PackageInstalledInfo res = data.res;
+ final String packageName = res.pkg.applicationInfo.packageName;
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
res.removedInfo.sendBroadcast(false, true, false);
@@ -1346,22 +1358,18 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
- res.pkg.applicationInfo.packageName,
- extras, null, null, firstUsers);
+ packageName, extras, null, null, firstUsers);
final boolean update = res.removedInfo.removedPackage != null;
if (update) {
extras.putBoolean(Intent.EXTRA_REPLACING, true);
}
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
- res.pkg.applicationInfo.packageName,
- extras, null, null, updateUsers);
+ packageName, extras, null, null, updateUsers);
if (update) {
sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
- res.pkg.applicationInfo.packageName,
- extras, null, null, updateUsers);
+ packageName, extras, null, null, updateUsers);
sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
- null, null,
- res.pkg.applicationInfo.packageName, null, updateUsers);
+ null, null, packageName, null, updateUsers);
// treat asec-hosted packages like removable media on upgrade
if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
@@ -1371,7 +1379,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
ArrayList<String> pkgList = new ArrayList<String>(1);
- pkgList.add(res.pkg.applicationInfo.packageName);
+ pkgList.add(packageName);
sendResourcesChangedBroadcast(true, true,
pkgList,uidArray, null);
}
@@ -1381,6 +1389,19 @@ public class PackageManagerService extends IPackageManager.Stub {
deleteOld = true;
}
+ // If this app is a browser and it's newly-installed for some
+ // users, clear any default-browser state in those users
+ if (firstUsers.length > 0) {
+ // the app's nature doesn't depend on the user, so we can just
+ // check its browser nature in any user and generalize.
+ if (packageIsBrowser(packageName, firstUsers[0])) {
+ synchronized (mPackages) {
+ for (int userId : firstUsers) {
+ mSettings.setDefaultBrowserPackageNameLPw(null, userId);
+ }
+ }
+ }
+ }
// Log current value of "unknown sources" setting
EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
getUnknownSourcesSettings());
@@ -2188,7 +2209,8 @@ public class PackageManagerService extends IPackageManager.Stub {
// If this is the first boot, and it is a normal boot, then
// we need to initialize the default preferred apps.
if (!mRestoredSettings && !onlyCore) {
- mSettings.readDefaultPreferredAppsLPw(this, 0);
+ mSettings.applyDefaultPreferredAppsLPw(this, UserHandle.USER_OWNER);
+ applyFactoryDefaultBrowserLPw(UserHandle.USER_OWNER);
}
// If this is first boot after an OTA, and a normal boot, then
@@ -2372,13 +2394,80 @@ public class PackageManagerService extends IPackageManager.Stub {
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "End priming domain verifications");
}
+ private void applyFactoryDefaultBrowserLPw(int userId) {
+ // The default browser app's package name is stored in a string resource,
+ // with a product-specific overlay used for vendor customization.
+ String browserPkg = mContext.getResources().getString(
+ com.android.internal.R.string.default_browser);
+ if (browserPkg != null) {
+ // non-empty string => required to be a known package
+ PackageSetting ps = mSettings.mPackages.get(browserPkg);
+ if (ps == null) {
+ Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
+ browserPkg = null;
+ } else {
+ mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
+ }
+ }
+
+ // Nothing valid explicitly set? Make the factory-installed browser the explicit
+ // default. If there's more than one, just leave everything alone.
+ if (browserPkg == null) {
+ calculateDefaultBrowserLPw(userId);
+ }
+ }
+
+ private void calculateDefaultBrowserLPw(int userId) {
+ List<String> allBrowsers = resolveAllBrowserApps(userId);
+ final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
+ mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
+ }
+
+ private List<String> resolveAllBrowserApps(int userId) {
+ // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
+ List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null,
+ PackageManager.MATCH_ALL, userId);
+
+ final int count = list.size();
+ List<String> result = new ArrayList<String>(count);
+ for (int i=0; i<count; i++) {
+ ResolveInfo info = list.get(i);
+ if (info.activityInfo == null
+ || !info.handleAllWebDataURI
+ || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
+ || result.contains(info.activityInfo.packageName)) {
+ continue;
+ }
+ result.add(info.activityInfo.packageName);
+ }
+
+ return result;
+ }
+
+ private boolean packageIsBrowser(String packageName, int userId) {
+ List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null,
+ PackageManager.MATCH_ALL, userId);
+ final int N = list.size();
+ for (int i = 0; i < N; i++) {
+ ResolveInfo info = list.get(i);
+ if (packageName.equals(info.activityInfo.packageName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private void checkDefaultBrowser() {
final int myUserId = UserHandle.myUserId();
final String packageName = getDefaultBrowserPackageName(myUserId);
- PackageInfo info = getPackageInfo(packageName, 0, myUserId);
- if (info == null) {
- Slog.w(TAG, "Default browser no longer installed: " + packageName);
- setDefaultBrowserPackageName(null, myUserId);
+ if (packageName != null) {
+ PackageInfo info = getPackageInfo(packageName, 0, myUserId);
+ if (info == null) {
+ Slog.w(TAG, "Default browser no longer installed: " + packageName);
+ synchronized (mPackages) {
+ applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1
+ }
+ }
}
}
@@ -2562,6 +2651,21 @@ public class PackageManagerService extends IPackageManager.Stub {
return null;
}
+ @Override
+ public int getMountExternalMode(int uid) {
+ if (Process.isIsolated(uid)) {
+ return Zygote.MOUNT_EXTERNAL_NONE;
+ } else {
+ if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_GRANTED) {
+ return Zygote.MOUNT_EXTERNAL_WRITE;
+ } else if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_GRANTED) {
+ return Zygote.MOUNT_EXTERNAL_READ;
+ } else {
+ return Zygote.MOUNT_EXTERNAL_DEFAULT;
+ }
+ }
+ }
+
static PermissionInfo generatePermissionInfo(
BasePermission bp, int flags) {
if (bp.perm != null) {
@@ -3201,6 +3305,7 @@ public class PackageManagerService extends IPackageManager.Stub {
enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
"grantRuntimePermission");
+ final int uid;
final SettingBase sb;
synchronized (mPackages) {
@@ -3216,6 +3321,7 @@ public class PackageManagerService extends IPackageManager.Stub {
enforceDeclaredAsUsedAndRuntimePermission(pkg, bp);
+ uid = pkg.applicationInfo.uid;
sb = (SettingBase) pkg.mExtras;
if (sb == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
@@ -3245,11 +3351,22 @@ public class PackageManagerService extends IPackageManager.Stub {
} break;
}
- mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
+ mOnPermissionChangeListeners.onPermissionsChanged(uid);
// Not critical if that is lost - app has to request again.
mSettings.writeRuntimePermissionsForUserLPr(userId, false);
}
+
+ if (READ_EXTERNAL_STORAGE.equals(name)
+ || WRITE_EXTERNAL_STORAGE.equals(name)) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ final StorageManager storage = mContext.getSystemService(StorageManager.class);
+ storage.remountUid(uid);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
}
@Override
@@ -3309,6 +3426,32 @@ public class PackageManagerService extends IPackageManager.Stub {
}
@Override
+ public void resetRuntimePermissions() {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.GRANT_REVOKE_PERMISSIONS,
+ "revokeRuntimePermission");
+
+ int callingUid = Binder.getCallingUid();
+ if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+ "resetRuntimePermissions");
+ }
+
+ final int[] userIds;
+
+ synchronized (mPackages) {
+ updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
+ final int userCount = UserManagerService.getInstance().getUserIds().length;
+ userIds = Arrays.copyOf(UserManagerService.getInstance().getUserIds(), userCount);
+ }
+
+ for (int userId : userIds) {
+ mDefaultPermissionPolicy.grantDefaultPermissions(userId);
+ }
+ }
+
+ @Override
public int getPermissionFlags(String name, String packageName, int userId) {
if (!sUserManager.exists(userId)) {
return 0;
@@ -4305,7 +4448,7 @@ public class PackageManagerService extends IPackageManager.Stub {
private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
String resolvedType, int flags, int sourceUserId, int parentUserId) {
- if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_APP_LINKING,
+ if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
sourceUserId)) {
return null;
}
@@ -4412,7 +4555,7 @@ public class PackageManagerService extends IPackageManager.Stub {
synchronized (mPackages) {
final int count = candidates.size();
- // First, try to use the domain prefered App. Partition the candidates into four lists:
+ // First, try to use the domain preferred app. Partition the candidates into four lists:
// one for the final results, one for the "do not use ever", one for "undefined status"
// and finally one for "Browser App type".
for (int n=0; n<count; n++) {
@@ -8239,6 +8382,14 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
if (!allowed && (bp.protectionLevel
+ & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
+ && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.MNC) {
+ // If this was a previously normal/dangerous permission that got moved
+ // to a system permission as part of the runtime permission redesign, then
+ // we still want to blindly grant it to old apps.
+ allowed = true;
+ }
+ if (!allowed && (bp.protectionLevel
& PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
// For development permissions, a development permission
// is granted only if it was already granted.
@@ -9047,7 +9198,8 @@ public class PackageManagerService extends IPackageManager.Stub {
IActivityManager am = ActivityManagerNative.getDefault();
if (am != null) {
try {
- am.startService(null, intent, null, UserHandle.USER_OWNER);
+ am.startService(null, intent, null, mContext.getOpPackageName(),
+ UserHandle.USER_OWNER);
} catch (RemoteException e) {
}
}
@@ -9546,6 +9698,9 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
+
boolean result = false;
synchronized (mPackages) {
result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
@@ -9587,12 +9742,17 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public boolean setDefaultBrowserPackageName(String packageName, int userId) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
+
synchronized (mPackages) {
- boolean result = mSettings.setDefaultBrowserPackageNameLPr(packageName, userId);
+ boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
if (packageName != null) {
result |= updateIntentVerificationStatus(packageName,
PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
UserHandle.myUserId());
+ mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
+ packageName, userId);
}
return result;
}
@@ -12020,7 +12180,7 @@ public class PackageManagerService extends IPackageManager.Stub {
final int verificationId = mIntentFilterVerificationToken++;
for (PackageParser.Activity a : pkg.activities) {
for (ActivityIntentInfo filter : a.intents) {
- if (filter.hasOnlyWebDataURI() && needsNetworkVerificationLPr(filter)) {
+ if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
"Verification needed for IntentFilter:" + filter.toString());
mIntentFilterVerifier.addOneIntentFilterVerification(
@@ -12908,7 +13068,7 @@ public class PackageManagerService extends IPackageManager.Stub {
* @param flags The flags that is going to be reset.
*/
private void revokeRuntimePermissionsAndClearFlagsLocked(
- PermissionsState permissionsState, int userId, int flags) {
+ PermissionsState permissionsState, final int userId, int flags) {
boolean needsWrite = false;
for (PermissionState state : permissionsState.getRuntimePermissionStates(userId)) {
@@ -12921,7 +13081,12 @@ public class PackageManagerService extends IPackageManager.Stub {
}
// Ensure default permissions are never cleared.
- mDefaultPermissionPolicy.grantDefaultPermissions(userId);
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mDefaultPermissionPolicy.grantDefaultPermissions(userId);
+ }
+ });
if (needsWrite) {
mSettings.writeRuntimePermissionsForUserLPr(userId, true);
@@ -13348,15 +13513,15 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public void resetPreferredActivities(int userId) {
- /* TODO: Actually use userId. Why is it being passed in? */
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
// writer
synchronized (mPackages) {
- int user = UserHandle.getCallingUserId();
- clearPackagePreferredActivitiesLPw(null, user);
- mSettings.readDefaultPreferredAppsLPw(this, user);
- scheduleWritePackageRestrictionsLocked(user);
+ clearPackagePreferredActivitiesLPw(null, userId);
+ mSettings.applyDefaultPreferredAppsLPw(this, userId);
+ applyFactoryDefaultBrowserLPw(userId);
+
+ scheduleWritePackageRestrictionsLocked(userId);
}
}
@@ -13992,6 +14157,8 @@ public class PackageManagerService extends IPackageManager.Stub {
Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
}
+ int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
+
synchronized (mPackages) {
// Verify that all of the preferred activity components actually
// exist. It is possible for applications to be updated and at
@@ -14021,15 +14188,19 @@ public class PackageManagerService extends IPackageManager.Stub {
mSettings.mPreferredActivities.keyAt(i));
}
}
+
+ for (int userId : UserManagerService.getInstance().getUserIds()) {
+ if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
+ grantPermissionsUserIds = ArrayUtils.appendInt(
+ grantPermissionsUserIds, userId);
+ }
+ }
}
sUserManager.systemReady();
// If we upgraded grant all default permissions before kicking off.
- if (isFirstBoot() || (CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE && mIsUpgrade)) {
- updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
- for (int userId : UserManagerService.getInstance().getUserIds()) {
- mDefaultPermissionPolicy.grantDefaultPermissions(userId);
- }
+ for (int userId : grantPermissionsUserIds) {
+ mDefaultPermissionPolicy.grantDefaultPermissions(userId);
}
// Kick off any messages waiting for system ready
@@ -14159,6 +14330,7 @@ public class PackageManagerService extends IPackageManager.Stub {
boolean checkin = false;
String packageName = null;
+ ArraySet<String> permissionNames = null;
int opti = 0;
while (opti < args.length) {
@@ -14182,6 +14354,7 @@ public class PackageManagerService extends IPackageManager.Stub {
pw.println(" k[eysets]: print known keysets");
pw.println(" r[esolvers]: dump intent resolvers");
pw.println(" perm[issions]: dump permissions");
+ pw.println(" permission [name ...]: dump declaration and use of given permission");
pw.println(" pref[erred]: print preferred package settings");
pw.println(" preferred-xml [--full]: print preferred package settings as xml");
pw.println(" prov[iders]: dump content providers");
@@ -14223,6 +14396,18 @@ public class PackageManagerService extends IPackageManager.Stub {
dumpState.setDump(DumpState.DUMP_RESOLVERS);
} else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_PERMISSIONS);
+ } else if ("permission".equals(cmd)) {
+ if (opti >= args.length) {
+ pw.println("Error: permission requires permission name");
+ return;
+ }
+ permissionNames = new ArraySet<>();
+ while (opti < args.length) {
+ permissionNames.add(args[opti]);
+ opti++;
+ }
+ dumpState.setDump(DumpState.DUMP_PERMISSIONS
+ | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
} else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_PREFERRED);
} else if ("preferred-xml".equals(cmd)) {
@@ -14505,8 +14690,8 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
- mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
- if (packageName == null) {
+ mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
+ if (packageName == null && permissionNames == null) {
for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
if (iperm == 0) {
if (dumpState.onTitlePrinted())
@@ -14566,11 +14751,11 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
- mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
+ mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
}
if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
- mSettings.dumpSharedUsersLPr(pw, packageName, dumpState, checkin);
+ mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
@@ -15418,6 +15603,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (mInstaller != null) {
mInstaller.createUserConfig(userHandle);
mSettings.createNewUserLILPw(this, mInstaller, userHandle, path);
+ applyFactoryDefaultBrowserLPw(userHandle);
}
}
@@ -15804,48 +15990,56 @@ public class PackageManagerService extends IPackageManager.Stub {
mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
}
}
- }
- @Override
- public void grantDefaultPermissions(final int userId) {
- enforceSystemOrPhoneCaller("grantDefaultPermissions");
- long token = Binder.clearCallingIdentity();
- try {
- // We cannot grant the default permissions with a lock held as
- // we query providers from other components for default handlers
- // such as enabled IMEs, etc.
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mDefaultPermissionPolicy.grantDefaultPermissions(userId);
- }
- });
- } finally {
- Binder.restoreCallingIdentity(token);
+ @Override
+ public void setSmsAppPackagesProvider(PackagesProvider provider) {
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
+ }
+ }
+
+ @Override
+ public void setDialerAppPackagesProvider(PackagesProvider provider) {
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
+ }
+ }
+
+ @Override
+ public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.setSyncAdapterPackagesProviderrLPw(provider);
+ }
+ }
+
+ @Override
+ public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
+ packageName, userId);
+ }
+ }
+
+ @Override
+ public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
+ packageName, userId);
+ }
}
}
@Override
- public void setCarrierAppPackagesProvider(final IPackagesProvider provider) {
- enforceSystemOrPhoneCaller("setCarrierAppPackagesProvider");
- long token = Binder.clearCallingIdentity();
- try {
- PackageManagerInternal.PackagesProvider wrapper =
- new PackageManagerInternal.PackagesProvider() {
- @Override
- public String[] getPackages(int userId) {
- try {
- return provider.getPackages(userId);
- } catch (RemoteException e) {
- return null;
- }
- }
- };
- synchronized (mPackages) {
- mDefaultPermissionPolicy.setCarrierAppPackagesProviderLPw(wrapper);
+ public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
+ enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
+ synchronized (mPackages) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
+ packageNames, userId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
- } finally {
- Binder.restoreCallingIdentity(token);
}
}
diff --git a/services/core/java/com/android/server/pm/PermissionsState.java b/services/core/java/com/android/server/pm/PermissionsState.java
index 04beafd..57ef284 100644
--- a/services/core/java/com/android/server/pm/PermissionsState.java
+++ b/services/core/java/com/android/server/pm/PermissionsState.java
@@ -219,6 +219,22 @@ public final class PermissionsState {
}
/**
+ * Returns whether the state has any known request for the given permission name,
+ * whether or not it has been granted.
+ */
+ public boolean hasRequestedPermission(ArraySet<String> names) {
+ if (mPermissions == null) {
+ return false;
+ }
+ for (int i=names.size()-1; i>=0; i--) {
+ if (mPermissions.get(names.valueAt(i)) != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* Gets all permissions for a given device user id regardless if they
* are install time or runtime permissions.
*
@@ -446,7 +462,7 @@ public final class PermissionsState {
}
}
- return permissionStates;
+ return permissionStates;
}
private int grantPermission(BasePermission permission, int userId) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index dcd7799..0ad2b4a 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -195,6 +195,7 @@ final class Settings {
private static final String ATTR_BLOCK_UNINSTALL = "blockUninstall";
private static final String ATTR_DOMAIN_VERIFICATON_STATE = "domainVerificationStatus";
private static final String ATTR_PACKAGE_NAME= "packageName";
+ private static final String ATTR_FINGERPRINT = "fingerprint";
private final Object mLock;
@@ -1130,7 +1131,7 @@ final class Settings {
return result;
}
- boolean setDefaultBrowserPackageNameLPr(String packageName, int userId) {
+ boolean setDefaultBrowserPackageNameLPw(String packageName, int userId) {
if (userId == UserHandle.USER_ALL) {
return false;
}
@@ -1177,6 +1178,16 @@ final class Settings {
}
}
+ boolean areDefaultRuntimePermissionsGrantedLPr(int userId) {
+ return mRuntimePermissionsPersistence
+ .areDefaultRuntimPermissionsGrantedLPr(userId);
+ }
+
+ void onDefaultRuntimePermissionsGrantedLPr(int userId) {
+ mRuntimePermissionsPersistence
+ .onDefaultRuntimePermissionsGrantedLPr(userId);
+ }
+
/**
* Returns whether the current database has is older than {@code version}
* for apps on internal storage.
@@ -2710,7 +2721,7 @@ final class Settings {
return true;
}
- void readDefaultPreferredAppsLPw(PackageManagerService service, int userId) {
+ void applyDefaultPreferredAppsLPw(PackageManagerService service, int userId) {
// First pull data from any pre-installed apps.
for (PackageSetting ps : mPackages.values()) {
if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null
@@ -3618,7 +3629,7 @@ final class Settings {
UserHandle.getUid(userHandle, ps.appId), userHandle,
ps.pkg.applicationInfo.seinfo);
}
- readDefaultPreferredAppsLPw(service, userHandle);
+ applyDefaultPreferredAppsLPw(service, userHandle);
writePackageRestrictionsLPr(userHandle);
writePackageListLPr(userHandle);
}
@@ -3881,8 +3892,9 @@ final class Settings {
ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
};
- void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, PackageSetting ps,
- SimpleDateFormat sdf, Date date, List<UserInfo> users) {
+ void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag,
+ ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf,
+ Date date, List<UserInfo> users) {
if (checkinTag != null) {
pw.print(checkinTag);
pw.print(",");
@@ -3953,10 +3965,13 @@ final class Settings {
}
pw.print(prefix); pw.print(" pkg="); pw.println(ps.pkg);
pw.print(prefix); pw.print(" codePath="); pw.println(ps.codePathString);
- pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.resourcePathString);
- pw.print(prefix); pw.print(" legacyNativeLibraryDir="); pw.println(ps.legacyNativeLibraryPathString);
- pw.print(prefix); pw.print(" primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
- pw.print(prefix); pw.print(" secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
+ if (permissionNames == null) {
+ pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.resourcePathString);
+ pw.print(prefix); pw.print(" legacyNativeLibraryDir=");
+ pw.println(ps.legacyNativeLibraryPathString);
+ pw.print(prefix); pw.print(" primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
+ pw.print(prefix); pw.print(" secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
+ }
pw.print(prefix); pw.print(" versionCode="); pw.print(ps.versionCode);
if (ps.pkg != null) {
pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
@@ -3969,8 +3984,10 @@ final class Settings {
pw.println(ps.pkg.applicationInfo.toString());
pw.print(prefix); pw.print(" flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
FLAG_DUMP_SPEC); pw.println();
- pw.print(prefix); pw.print(" priavateFlags="); printFlags(pw,
- ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();
+ if (ps.pkg.applicationInfo.privateFlags != 0) {
+ pw.print(prefix); pw.print(" privateFlags="); printFlags(pw,
+ ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();
+ }
pw.print(prefix); pw.print(" dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
pw.print(prefix); pw.print(" supportsScreens=[");
boolean first = true;
@@ -4063,9 +4080,9 @@ final class Settings {
pw.print(prefix); pw.print(" pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
pw.println();
- if (ps.sharedUser == null) {
+ if (ps.sharedUser == null || permissionNames != null) {
PermissionsState permissionsState = ps.getPermissionsState();
- dumpInstallPermissionsLPr(pw, prefix + " ", permissionsState);
+ dumpInstallPermissionsLPr(pw, prefix + " ", permissionNames, permissionsState);
}
for (UserInfo user : users) {
@@ -4089,28 +4106,31 @@ final class Settings {
if (ps.sharedUser == null) {
PermissionsState permissionsState = ps.getPermissionsState();
dumpGidsLPr(pw, prefix + " ", permissionsState.computeGids(user.id));
- dumpRuntimePermissionsLPr(pw, prefix + " ", permissionsState
+ dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissionsState
.getRuntimePermissionStates(user.id));
}
- ArraySet<String> cmp = ps.getDisabledComponents(user.id);
- if (cmp != null && cmp.size() > 0) {
- pw.print(prefix); pw.println(" disabledComponents:");
- for (String s : cmp) {
- pw.print(prefix); pw.print(" "); pw.println(s);
+ if (permissionNames == null) {
+ ArraySet<String> cmp = ps.getDisabledComponents(user.id);
+ if (cmp != null && cmp.size() > 0) {
+ pw.print(prefix); pw.println(" disabledComponents:");
+ for (String s : cmp) {
+ pw.print(prefix); pw.print(" "); pw.println(s);
+ }
}
- }
- cmp = ps.getEnabledComponents(user.id);
- if (cmp != null && cmp.size() > 0) {
- pw.print(prefix); pw.println(" enabledComponents:");
- for (String s : cmp) {
- pw.print(prefix); pw.print(" "); pw.println(s);
+ cmp = ps.getEnabledComponents(user.id);
+ if (cmp != null && cmp.size() > 0) {
+ pw.print(prefix); pw.println(" enabledComponents:");
+ for (String s : cmp) {
+ pw.print(prefix); pw.print(" "); pw.println(s);
+ }
}
}
}
}
- void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState, boolean checkin) {
+ void dumpPackagesLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
+ DumpState dumpState, boolean checkin) {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
final Date date = new Date();
boolean printedSomething = false;
@@ -4120,6 +4140,10 @@ final class Settings {
&& !packageName.equals(ps.name)) {
continue;
}
+ if (permissionNames != null
+ && !ps.getPermissionsState().hasRequestedPermission(permissionNames)) {
+ continue;
+ }
if (!checkin && packageName != null) {
dumpState.setSharedUser(ps.sharedUser);
@@ -4131,11 +4155,11 @@ final class Settings {
pw.println("Packages:");
printedSomething = true;
}
- dumpPackageLPr(pw, " ", checkin ? "pkg" : null, ps, sdf, date, users);
+ dumpPackageLPr(pw, " ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users);
}
printedSomething = false;
- if (!checkin && mRenamedPackages.size() > 0) {
+ if (!checkin && mRenamedPackages.size() > 0 && permissionNames == null) {
for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
if (packageName != null && !packageName.equals(e.getKey())
&& !packageName.equals(e.getValue())) {
@@ -4159,7 +4183,7 @@ final class Settings {
}
printedSomething = false;
- if (mDisabledSysPackages.size() > 0) {
+ if (mDisabledSysPackages.size() > 0 && permissionNames == null) {
for (final PackageSetting ps : mDisabledSysPackages.values()) {
if (packageName != null && !packageName.equals(ps.realName)
&& !packageName.equals(ps.name)) {
@@ -4171,17 +4195,22 @@ final class Settings {
pw.println("Hidden system packages:");
printedSomething = true;
}
- dumpPackageLPr(pw, " ", checkin ? "dis" : null, ps, sdf, date, users);
+ dumpPackageLPr(pw, " ", checkin ? "dis" : null, permissionNames, ps, sdf, date,
+ users);
}
}
}
- void dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState) {
+ void dumpPermissionsLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
+ DumpState dumpState) {
boolean printedSomething = false;
for (BasePermission p : mPermissions.values()) {
if (packageName != null && !packageName.equals(p.sourcePackage)) {
continue;
}
+ if (permissionNames != null && !permissionNames.contains(p.name)) {
+ continue;
+ }
if (!printedSomething) {
if (dumpState.onTitlePrinted())
pw.println();
@@ -4211,13 +4240,17 @@ final class Settings {
}
}
- void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState,
- boolean checkin) {
+ void dumpSharedUsersLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
+ DumpState dumpState, boolean checkin) {
boolean printedSomething = false;
for (SharedUserSetting su : mSharedUsers.values()) {
if (packageName != null && su != dumpState.getSharedUser()) {
continue;
}
+ if (permissionNames != null
+ && !su.getPermissionsState().hasRequestedPermission(permissionNames)) {
+ continue;
+ }
if (!checkin) {
if (!printedSomething) {
if (dumpState.onTitlePrinted())
@@ -4235,7 +4268,7 @@ final class Settings {
pw.print(prefix); pw.print("userId="); pw.println(su.userId);
PermissionsState permissionsState = su.getPermissionsState();
- dumpInstallPermissionsLPr(pw, prefix, permissionsState);
+ dumpInstallPermissionsLPr(pw, prefix, permissionNames, permissionsState);
for (int userId : UserManagerService.getInstance().getUserIds()) {
final int[] gids = permissionsState.computeGids(userId);
@@ -4244,7 +4277,7 @@ final class Settings {
if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) {
pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": ");
dumpGidsLPr(pw, prefix + " ", gids);
- dumpRuntimePermissionsLPr(pw, prefix + " ", permissions);
+ dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissions);
}
}
} else {
@@ -4289,11 +4322,15 @@ final class Settings {
}
}
- void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix,
+ void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
List<PermissionState> permissionStates) {
if (!permissionStates.isEmpty()) {
pw.print(prefix); pw.println("runtime permissions:");
for (PermissionState permissionState : permissionStates) {
+ if (permissionNames != null
+ && !permissionNames.contains(permissionState.getName())) {
+ continue;
+ }
pw.print(prefix); pw.print(" "); pw.print(permissionState.getName());
pw.print(", granted="); pw.print(permissionState.isGranted());
pw.print(", flags=0x"); pw.println(Integer.toHexString(
@@ -4302,12 +4339,16 @@ final class Settings {
}
}
- void dumpInstallPermissionsLPr(PrintWriter pw, String prefix,
+ void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
PermissionsState permissionsState) {
List<PermissionState> permissionStates = permissionsState.getInstallPermissionStates();
if (!permissionStates.isEmpty()) {
pw.print(prefix); pw.println("install permissions:");
for (PermissionState permissionState : permissionStates) {
+ if (permissionNames != null
+ && !permissionNames.contains(permissionState.getName())) {
+ continue;
+ }
pw.print(prefix); pw.print(" "); pw.print(permissionState.getName());
pw.print(", granted="); pw.print(permissionState.isGranted());
pw.print(", flags=0x"); pw.println(Integer.toHexString(
@@ -4334,15 +4375,33 @@ final class Settings {
private final Object mLock;
@GuardedBy("mLock")
- private SparseBooleanArray mWriteScheduled = new SparseBooleanArray();
+ private final SparseBooleanArray mWriteScheduled = new SparseBooleanArray();
+
+ @GuardedBy("mLock")
+ // The mapping keys are user ids.
+ private final SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray();
+
+ @GuardedBy("mLock")
+ // The mapping keys are user ids.
+ private final SparseArray<String> mFingerprints = new SparseArray<>();
@GuardedBy("mLock")
- private SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray();
+ // The mapping keys are user ids.
+ private final SparseBooleanArray mDefaultPermissionsGranted = new SparseBooleanArray();
public RuntimePermissionPersistence(Object lock) {
mLock = lock;
}
+ public boolean areDefaultRuntimPermissionsGrantedLPr(int userId) {
+ return mDefaultPermissionsGranted.get(userId);
+ }
+
+ public void onDefaultRuntimePermissionsGrantedLPr(int userId) {
+ mFingerprints.put(userId, Build.FINGERPRINT);
+ writePermissionsForUserAsyncLPr(userId);
+ }
+
public void writePermissionsForUserSyncLPr(int userId) {
mHandler.removeMessages(userId);
writePermissionsSync(userId);
@@ -4427,6 +4486,11 @@ final class Settings {
serializer.startDocument(null, true);
serializer.startTag(null, TAG_RUNTIME_PERMISSIONS);
+ String fingerprint = mFingerprints.get(userId);
+ if (fingerprint != null) {
+ serializer.attribute(null, ATTR_FINGERPRINT, fingerprint);
+ }
+
final int packageCount = permissionsForPackage.size();
for (int i = 0; i < packageCount; i++) {
String packageName = permissionsForPackage.keyAt(i);
@@ -4451,7 +4515,10 @@ final class Settings {
serializer.endDocument();
destination.finishWrite(out);
- // Any error while writing is fatal.
+ if (Build.FINGERPRINT.equals(fingerprint)) {
+ mDefaultPermissionsGranted.put(userId, true);
+ }
+ // Any error while writing is fatal.
} catch (Throwable t) {
Slog.wtf(PackageManagerService.TAG,
"Failed to write settings, restoring backup", t);
@@ -4529,6 +4596,13 @@ final class Settings {
}
switch (parser.getName()) {
+ case TAG_RUNTIME_PERMISSIONS: {
+ String fingerprint = parser.getAttributeValue(null, ATTR_FINGERPRINT);
+ mFingerprints.put(userId, fingerprint);
+ final boolean defaultsGranted = Build.FINGERPRINT.equals(fingerprint);
+ mDefaultPermissionsGranted.put(userId, defaultsGranted);
+ } break;
+
case TAG_PACKAGE: {
String name = parser.getAttributeValue(null, ATTR_NAME);
PackageSetting ps = mPackages.get(name);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 8a8d2a6..4300df6 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -972,7 +972,7 @@ public class UserManagerService extends IUserManager.Stub {
writeBoolean(serializer, restrictions, UserManager.DISALLOW_OUTGOING_BEAM);
writeBoolean(serializer, restrictions, UserManager.DISALLOW_WALLPAPER);
writeBoolean(serializer, restrictions, UserManager.DISALLOW_SAFE_BOOT);
- writeBoolean(serializer, restrictions, UserManager.ALLOW_PARENT_APP_LINKING);
+ writeBoolean(serializer, restrictions, UserManager.ALLOW_PARENT_PROFILE_APP_LINKING);
serializer.endTag(null, TAG_RESTRICTIONS);
}
@@ -1104,7 +1104,7 @@ public class UserManagerService extends IUserManager.Stub {
readBoolean(parser, restrictions, UserManager.DISALLOW_OUTGOING_BEAM);
readBoolean(parser, restrictions, UserManager.DISALLOW_WALLPAPER);
readBoolean(parser, restrictions, UserManager.DISALLOW_SAFE_BOOT);
- readBoolean(parser, restrictions, UserManager.ALLOW_PARENT_APP_LINKING);
+ readBoolean(parser, restrictions, UserManager.ALLOW_PARENT_PROFILE_APP_LINKING);
}
private void readBoolean(XmlPullParser parser, Bundle restrictions,
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 93e1f18..3393d7d 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -51,6 +51,7 @@ import android.media.IAudioService;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.media.session.MediaSessionLegacyHelper;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
import android.os.FactoryTest;
@@ -61,6 +62,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -93,6 +95,8 @@ import android.view.KeyCharacterMap;
import android.view.KeyCharacterMap.FallbackAction;
import android.view.KeyEvent;
import android.view.MotionEvent;
+
+import com.android.internal.logging.MetricsLogger;
import com.android.internal.policy.PhoneWindow;
import android.view.Surface;
import android.view.View;
@@ -267,6 +271,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
SearchManager mSearchManager;
AccessibilityManager mAccessibilityManager;
BurnInProtectionHelper mBurnInProtectionHelper;
+ AppOpsManager mAppOpsManager;
// Vibrator pattern for haptic feedback of a long press.
long[] mLongPressVibePattern;
@@ -544,6 +549,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Display mDisplay;
+ private int mDisplayRotation;
+
int mLandscapeRotation = 0; // default landscape rotation
int mSeascapeRotation = 0; // "other" landscape rotation, 180 degrees from mLandscapeRotation
int mPortraitRotation = 0; // default portrait rotation
@@ -1034,6 +1041,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case MULTI_PRESS_POWER_NOTHING:
break;
case MULTI_PRESS_POWER_THEATER_MODE:
+ if (!isUserSetupComplete()) {
+ Slog.i(TAG, "Ignoring toggling theater mode - device not setup.");
+ break;
+ }
+
if (isTheaterModeEnabled()) {
Slog.i(TAG, "Toggling theater mode off.");
Settings.Global.putInt(mContext.getContentResolver(),
@@ -1255,6 +1267,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
+ mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
// Init display burn-in protection
boolean burnInProtectionEnabled = context.getResources().getBoolean(
@@ -1689,6 +1702,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (mImmersiveModeConfirmation != null) {
mImmersiveModeConfirmation.loadSetting(mCurrentUserId);
}
+ }
+ synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
PolicyControl.reloadFromSetting(mContext);
}
if (updateRotation) {
@@ -1810,6 +1825,25 @@ public class PhoneWindowManager implements WindowManagerPolicy {
permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
}
if (permission != null) {
+ if (permission == android.Manifest.permission.SYSTEM_ALERT_WINDOW) {
+ final int callingUid = Binder.getCallingUid();
+ // check if this is a system uid first before bothering with
+ // obtaining package name
+ if (callingUid == Process.SYSTEM_UID) {
+ return WindowManagerGlobal.ADD_OKAY;
+ }
+
+ final int mode = mAppOpsManager.checkOp(outAppOp[0], callingUid,
+ attrs.packageName);
+ if (mode == AppOpsManager.MODE_DEFAULT) {
+ if (mContext.checkCallingPermission(permission) !=
+ PackageManager.PERMISSION_GRANTED) {
+ return WindowManagerGlobal.ADD_PERMISSION_DENIED;
+ }
+ }
+ return WindowManagerGlobal.ADD_OKAY;
+ }
+
if (mContext.checkCallingOrSelfPermission(permission)
!= PackageManager.PERMISSION_GRANTED) {
return WindowManagerGlobal.ADD_PERMISSION_DENIED;
@@ -3272,12 +3306,28 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
@Override
- public void getInsetHintLw(WindowManager.LayoutParams attrs, Rect outContentInsets,
- Rect outStableInsets) {
+ public void getInsetHintLw(WindowManager.LayoutParams attrs, int displayRotation,
+ Rect outContentInsets, Rect outStableInsets, Rect outOutsets) {
final int fl = PolicyControl.getWindowFlags(null, attrs);
final int sysuiVis = PolicyControl.getSystemUiVisibility(null, attrs);
final int systemUiVisibility = (sysuiVis | attrs.subtreeSystemUiVisibility);
+ final boolean useOutsets = outOutsets != null && shouldUseOutsets(attrs, fl);
+ if (useOutsets) {
+ int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources());
+ if (outset > 0) {
+ if (displayRotation == Surface.ROTATION_0) {
+ outOutsets.bottom += outset;
+ } else if (displayRotation == Surface.ROTATION_90) {
+ outOutsets.right += outset;
+ } else if (displayRotation == Surface.ROTATION_180) {
+ outOutsets.top += outset;
+ } else if (displayRotation == Surface.ROTATION_270) {
+ outOutsets.left += outset;
+ }
+ }
+ }
+
if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR))
== (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) {
int availRight, availBottom;
@@ -3317,10 +3367,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
outStableInsets.setEmpty();
}
+ private boolean shouldUseOutsets(WindowManager.LayoutParams attrs, int fl) {
+ return attrs.type == TYPE_WALLPAPER || (fl & (WindowManager.LayoutParams.FLAG_FULLSCREEN
+ | WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN)) != 0;
+ }
+
/** {@inheritDoc} */
@Override
public void beginLayoutLw(boolean isDefaultDisplay, int displayWidth, int displayHeight,
int displayRotation) {
+ mDisplayRotation = displayRotation;
final int overscanLeft, overscanTop, overscanRight, overscanBottom;
if (isDefaultDisplay) {
switch (displayRotation) {
@@ -4107,19 +4163,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// need to provide information to the clients that want to pretend that you can draw there.
// We only want to apply outsets to certain types of windows. For example, we never want to
// apply the outsets to floating dialogs, because they wouldn't make sense there.
- final boolean useOutsets = attrs.type == TYPE_WALLPAPER
- || (fl & (WindowManager.LayoutParams.FLAG_FULLSCREEN
- | WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN)) != 0;
+ final boolean useOutsets = shouldUseOutsets(attrs, fl);
if (isDefaultDisplay && useOutsets) {
osf = mTmpOutsetFrame;
osf.set(cf.left, cf.top, cf.right, cf.bottom);
int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources());
if (outset > 0) {
- int rotation = Surface.ROTATION_0;
- try {
- rotation = mWindowManager.getRotation();
- } catch (RemoteException e) {
- }
+ int rotation = mDisplayRotation;
if (rotation == Surface.ROTATION_0) {
osf.bottom += outset;
} else if (rotation == Surface.ROTATION_90) {
@@ -4219,7 +4269,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
/** {@inheritDoc} */
@Override
- public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs) {
+ public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs,
+ WindowState attached) {
if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisibleOrBehindKeyguardLw="
+ win.isVisibleOrBehindKeyguardLw());
final int fl = PolicyControl.getWindowFlags(win, attrs);
@@ -4264,8 +4315,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
- if (appWindow) {
- final IApplicationToken appToken = win.getAppToken();
+ final IApplicationToken appToken = win.getAppToken();
+
+ // For app windows that are not attached, we decide if all windows in the app they
+ // represent should be hidden or if we should hide the lockscreen. For attached app
+ // windows we defer the decision to the window it is attached to.
+ if (appWindow && attached == null) {
if (showWhenLocked) {
// Remove any previous windows with the same appToken.
mAppsToBeHidden.remove(appToken);
@@ -5323,6 +5378,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public void finishedGoingToSleep(int why) {
EventLog.writeEvent(70000, 0);
if (DEBUG_WAKEUP) Slog.i(TAG, "Finished going to sleep... (why=" + why + ")");
+ MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000);
// We must get this work done here because the power manager will drop
// the wake lock and let the system suspend once this function returns.
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 51bb36f..3f59755 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -2311,6 +2311,11 @@ public final class PowerManagerService extends SystemService
if (mDeviceIdleMode != enabled) {
mDeviceIdleMode = enabled;
updateWakeLockDisabledStatesLocked();
+ if (enabled) {
+ EventLogTags.writeDeviceIdleOnPhase("power");
+ } else {
+ EventLogTags.writeDeviceIdleOffPhase("power");
+ }
}
}
}
@@ -3117,7 +3122,7 @@ public final class PowerManagerService extends SystemService
return;
}
- if (eventTime > SystemClock.uptimeMillis()) {
+ if (eventTime > now) {
throw new IllegalArgumentException("event time must not be in the future");
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 7640837..5ceb6ad 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -571,11 +571,11 @@ public class StatusBarManagerService extends IStatusBarService.Stub {
* LED, vibration, and ringing
*/
@Override
- public void onPanelRevealed(boolean clearNotificationEffects) {
+ public void onPanelRevealed(boolean clearNotificationEffects, int numItems) {
enforceStatusBarService();
long identity = Binder.clearCallingIdentity();
try {
- mNotificationDelegate.onPanelRevealed(clearNotificationEffects);
+ mNotificationDelegate.onPanelRevealed(clearNotificationEffects, numItems);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/java/com/android/server/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
index 9abdf21..c2ce572 100644
--- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java
+++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
@@ -20,12 +20,24 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.content.pm.PackageManagerInternal;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.provider.Settings;
+import android.telecom.DefaultDialerManager;
+import android.util.IntArray;
import android.util.Slog;
+import android.util.SparseBooleanArray;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.telephony.SmsApplication;
+import com.android.server.LocalServices;
import com.android.server.SystemService;
/**
@@ -48,8 +60,43 @@ public class TelecomLoaderService extends SystemService {
connectToTelecom();
}
}, 0);
-
+ SmsApplication.getDefaultMmsApplication(mContext, false);
ServiceManager.addService(Context.TELECOM_SERVICE, service);
+
+ synchronized (mLock) {
+ if (mDefaultSmsAppRequests != null || mDefaultDialerAppRequests != null) {
+ final PackageManagerInternal packageManagerInternal = LocalServices
+ .getService(PackageManagerInternal.class);
+
+ if (mDefaultSmsAppRequests != null) {
+ ComponentName smsComponent = SmsApplication.getDefaultSmsApplication(
+ mContext, true);
+ if (smsComponent != null) {
+ final int requestCount = mDefaultSmsAppRequests.size();
+ for (int i = requestCount - 1; i >= 0; i--) {
+ final int userid = mDefaultSmsAppRequests.get(i);
+ mDefaultSmsAppRequests.remove(i);
+ packageManagerInternal.grantDefaultPermissionsToDefaultSmsApp(
+ smsComponent.getPackageName(), userid);
+ }
+ }
+ }
+
+ if (mDefaultDialerAppRequests != null) {
+ String packageName = DefaultDialerManager.getDefaultDialerApplication(
+ mContext);
+ if (packageName != null) {
+ final int requestCount = mDefaultDialerAppRequests.size();
+ for (int i = requestCount - 1; i >= 0; i--) {
+ final int userId = mDefaultDialerAppRequests.get(i);
+ mDefaultDialerAppRequests.remove(i);
+ packageManagerInternal.grantDefaultPermissionsToDefaultDialerApp(
+ packageName, userId);
+ }
+ }
+ }
+ }
+ }
} catch (RemoteException e) {
Slog.w(TAG, "Failed linking to death.");
}
@@ -67,12 +114,23 @@ public class TelecomLoaderService extends SystemService {
private static final String SERVICE_ACTION = "com.android.ITelecomService";
+ private final Object mLock = new Object();
+
+ @GuardedBy("mLock")
+ private IntArray mDefaultSmsAppRequests;
+
+ @GuardedBy("mLock")
+ private IntArray mDefaultDialerAppRequests;
+
private final Context mContext;
+
+ @GuardedBy("mLock")
private TelecomServiceConnection mServiceConnection;
public TelecomLoaderService(Context context) {
super(context);
mContext = context;
+ registerDefaultAppProviders();
}
@Override
@@ -82,26 +140,118 @@ public class TelecomLoaderService extends SystemService {
@Override
public void onBootPhase(int phase) {
if (phase == PHASE_ACTIVITY_MANAGER_READY) {
+ registerDefaultAppNotifier();
connectToTelecom();
}
}
private void connectToTelecom() {
- if (mServiceConnection != null) {
- // TODO: Is unbinding worth doing or wait for system to rebind?
- mContext.unbindService(mServiceConnection);
- mServiceConnection = null;
- }
+ synchronized (mLock) {
+ if (mServiceConnection != null) {
+ // TODO: Is unbinding worth doing or wait for system to rebind?
+ mContext.unbindService(mServiceConnection);
+ mServiceConnection = null;
+ }
- TelecomServiceConnection serviceConnection = new TelecomServiceConnection();
- Intent intent = new Intent(SERVICE_ACTION);
- intent.setComponent(SERVICE_COMPONENT);
- int flags = Context.BIND_IMPORTANT | Context.BIND_FOREGROUND_SERVICE
- | Context.BIND_AUTO_CREATE;
+ TelecomServiceConnection serviceConnection = new TelecomServiceConnection();
+ Intent intent = new Intent(SERVICE_ACTION);
+ intent.setComponent(SERVICE_COMPONENT);
+ int flags = Context.BIND_IMPORTANT | Context.BIND_FOREGROUND_SERVICE
+ | Context.BIND_AUTO_CREATE;
- // Bind to Telecom and register the service
- if (mContext.bindServiceAsUser(intent, serviceConnection, flags, UserHandle.OWNER)) {
- mServiceConnection = serviceConnection;
+ // Bind to Telecom and register the service
+ if (mContext.bindServiceAsUser(intent, serviceConnection, flags, UserHandle.OWNER)) {
+ mServiceConnection = serviceConnection;
+ }
}
}
+
+
+ private void registerDefaultAppProviders() {
+ final PackageManagerInternal packageManagerInternal = LocalServices.getService(
+ PackageManagerInternal.class);
+
+ // Set a callback for the package manager to query the default sms app.
+ packageManagerInternal.setSmsAppPackagesProvider(
+ new PackageManagerInternal.PackagesProvider() {
+ @Override
+ public String[] getPackages(int userId) {
+ synchronized (mLock) {
+ if (mServiceConnection == null) {
+ if (mDefaultSmsAppRequests == null) {
+ mDefaultSmsAppRequests = new IntArray();
+ }
+ mDefaultSmsAppRequests.add(userId);
+ return null;
+ }
+ }
+ ComponentName smsComponent = SmsApplication.getDefaultSmsApplication(
+ mContext, true);
+ if (smsComponent != null) {
+ return new String[]{smsComponent.getPackageName()};
+ }
+ return null;
+ }
+ });
+
+ // Set a callback for the package manager to query the default dialer app.
+ packageManagerInternal.setDialerAppPackagesProvider(
+ new PackageManagerInternal.PackagesProvider() {
+ @Override
+ public String[] getPackages(int userId) {
+ synchronized (mLock) {
+ if (mServiceConnection == null) {
+ if (mDefaultDialerAppRequests == null) {
+ mDefaultDialerAppRequests = new IntArray();
+ }
+ mDefaultDialerAppRequests.add(userId);
+ return null;
+ }
+ }
+ String packageName = DefaultDialerManager.getDefaultDialerApplication(mContext);
+ if (packageName != null) {
+ return new String[]{packageName};
+ }
+ return null;
+ }
+ });
+ }
+
+ private void registerDefaultAppNotifier() {
+ final PackageManagerInternal packageManagerInternal = LocalServices.getService(
+ PackageManagerInternal.class);
+
+ // Notify the package manager on default app changes
+ final Uri defaultSmsAppUri = Settings.Secure.getUriFor(
+ Settings.Secure.SMS_DEFAULT_APPLICATION);
+ final Uri defaultDialerAppUri = Settings.Secure.getUriFor(
+ Settings.Secure.DIALER_DEFAULT_APPLICATION);
+
+ ContentObserver contentObserver = new ContentObserver(
+ new Handler(Looper.getMainLooper())) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri, int userId) {
+ if (defaultSmsAppUri.equals(uri)) {
+ ComponentName smsComponent = SmsApplication.getDefaultSmsApplication(
+ mContext, true);
+ if (smsComponent != null) {
+ packageManagerInternal.grantDefaultPermissionsToDefaultSmsApp(
+ smsComponent.getPackageName(), userId);
+ }
+ } else if (defaultDialerAppUri.equals(uri)) {
+ String packageName = DefaultDialerManager.getDefaultDialerApplication(
+ mContext);
+ if (packageName != null) {
+ packageManagerInternal.grantDefaultPermissionsToDefaultDialerApp(
+ packageName, userId);
+ }
+ }
+ }
+ };
+
+ mContext.getContentResolver().registerContentObserver(defaultSmsAppUri,
+ false, contentObserver, UserHandle.USER_ALL);
+ mContext.getContentResolver().registerContentObserver(defaultDialerAppUri,
+ false, contentObserver, UserHandle.USER_ALL);
+ }
}
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 726db4e..15da829 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -105,7 +105,7 @@ public class TrustManagerService extends SystemService {
private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<AgentInfo>();
private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<ITrustListener>();
private final Receiver mReceiver = new Receiver();
- private final SparseBooleanArray mUserHasAuthenticatedSinceBoot = new SparseBooleanArray();
+ private final SparseBooleanArray mUserHasAuthenticated = new SparseBooleanArray();
/* package */ final TrustArchive mArchive = new TrustArchive();
private final Context mContext;
private final LockPatternUtils mLockPatternUtils;
@@ -118,6 +118,9 @@ public class TrustManagerService extends SystemService {
@GuardedBy("mDeviceLockedForUser")
private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
+ @GuardedBy("mUserHasAuthenticatedSinceBoot")
+ private final SparseBooleanArray mUserHasAuthenticatedSinceBoot = new SparseBooleanArray();
+
private boolean mTrustAgentsCanRun = false;
private int mCurrentUser = UserHandle.USER_OWNER;
@@ -556,31 +559,34 @@ public class TrustManagerService extends SystemService {
}
private boolean getUserHasAuthenticated(int userId) {
- synchronized (mUserHasAuthenticatedSinceBoot) {
- return mUserHasAuthenticatedSinceBoot.get(userId);
- }
+ return mUserHasAuthenticated.get(userId);
}
/**
* @return whether the value has changed
*/
private boolean setUserHasAuthenticated(int userId) {
- synchronized (mUserHasAuthenticatedSinceBoot) {
- if (!mUserHasAuthenticatedSinceBoot.get(userId)) {
+ if (!mUserHasAuthenticated.get(userId)) {
+ mUserHasAuthenticated.put(userId, true);
+ synchronized (mUserHasAuthenticatedSinceBoot) {
mUserHasAuthenticatedSinceBoot.put(userId, true);
- return true;
}
- return false;
+ return true;
}
+ return false;
}
private void clearUserHasAuthenticated(int userId) {
+ if (userId == UserHandle.USER_ALL) {
+ mUserHasAuthenticated.clear();
+ } else {
+ mUserHasAuthenticated.put(userId, false);
+ }
+ }
+
+ private boolean getUserHasAuthenticatedSinceBoot(int userId) {
synchronized (mUserHasAuthenticatedSinceBoot) {
- if (userId == UserHandle.USER_ALL) {
- mUserHasAuthenticatedSinceBoot.clear();
- } else {
- mUserHasAuthenticatedSinceBoot.put(userId, false);
- }
+ return mUserHasAuthenticatedSinceBoot.get(userId);
}
}
@@ -734,7 +740,7 @@ public class TrustManagerService extends SystemService {
Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, null);
long token = Binder.clearCallingIdentity();
try {
- return getUserHasAuthenticated(userId);
+ return getUserHasAuthenticatedSinceBoot(userId);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -788,6 +794,9 @@ public class TrustManagerService extends SystemService {
fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
+ fout.print(", hasAuthenticated=" + dumpBool(getUserHasAuthenticated(user.id)));
+ fout.print(", hasAuthenticatedSinceBoot="
+ + dumpBool(getUserHasAuthenticatedSinceBoot(user.id)));
fout.println();
fout.println(" Enabled agents:");
boolean duplicateSimpleNames = false;
@@ -909,7 +918,7 @@ public class TrustManagerService extends SystemService {
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
int userId = getUserId(intent);
if (userId > 0) {
- mUserHasAuthenticatedSinceBoot.delete(userId);
+ mUserHasAuthenticated.delete(userId);
synchronized (mUserIsTrusted) {
mUserIsTrusted.delete(userId);
}
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 5995e9c..0eee815 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -531,14 +531,14 @@ public class AppTransition implements Dump {
// Clip third of the from size of launch icon, expand to full width/height
Animation clipAnimLR = new ClipRectLRAnimation(
- centerX - mNextAppTransitionStartWidth / 3,
- centerX + mNextAppTransitionStartWidth / 3,
+ centerX - mNextAppTransitionStartWidth / 2,
+ centerX + mNextAppTransitionStartWidth / 2,
0, appWidth);
clipAnimLR.setInterpolator(mClipHorizontalInterpolator);
clipAnimLR.setDuration((long) (DEFAULT_APP_TRANSITION_DURATION / 2.5f));
Animation clipAnimTB = new ClipRectTBAnimation(
- centerY - mNextAppTransitionStartHeight / 3 - translationY,
- centerY + mNextAppTransitionStartHeight / 3 - translationY,
+ centerY - mNextAppTransitionStartHeight / 2 - translationY,
+ centerY + mNextAppTransitionStartHeight / 2 - translationY,
0, appHeight);
clipAnimTB.setInterpolator(mTouchResponseInterpolator);
clipAnimTB.setDuration(DEFAULT_APP_TRANSITION_DURATION);
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index e9c5ac7..a8ba0f9 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -158,15 +158,15 @@ final class Session extends IWindowSession.Stub
int viewVisibility, Rect outContentInsets, Rect outStableInsets,
InputChannel outInputChannel) {
return addToDisplay(window, seq, attrs, viewVisibility, Display.DEFAULT_DISPLAY,
- outContentInsets, outStableInsets, outInputChannel);
+ outContentInsets, outStableInsets, null /* outOutsets */, outInputChannel);
}
@Override
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets,
- InputChannel outInputChannel) {
+ Rect outOutsets, InputChannel outInputChannel) {
return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
- outContentInsets, outStableInsets, outInputChannel);
+ outContentInsets, outStableInsets, outOutsets, outInputChannel);
}
@Override
@@ -180,7 +180,7 @@ final class Session extends IWindowSession.Stub
public int addToDisplayWithoutInputChannel(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets) {
return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
- outContentInsets, outStableInsets, null);
+ outContentInsets, outStableInsets, null /* outOutsets */, null);
}
public void remove(IWindow window) {
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index d7b202d..76baaa7 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -343,7 +343,9 @@ public class WindowAnimator {
boolean applyExistingExitAnimation = mPostKeyguardExitAnimation != null
&& !winAnimator.mKeyguardGoingAwayAnimation
&& win.hasDrawnLw()
- && win.mAttachedWindow == null;
+ && win.mAttachedWindow == null
+ && !win.mIsImWindow
+ && displayId == Display.DEFAULT_DISPLAY;
// If the window is already showing and we don't need to apply an existing
// Keyguard exit animation, skip.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b285b66..fc86920 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2357,7 +2357,8 @@ public class WindowManagerService extends IWindowManager.Stub
public int addWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
- Rect outContentInsets, Rect outStableInsets, InputChannel outInputChannel) {
+ Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
+ InputChannel outInputChannel) {
int[] appOp = new int[1];
int res = mPolicy.checkAddPermission(attrs, appOp);
if (res != WindowManagerGlobal.ADD_OKAY) {
@@ -2594,7 +2595,8 @@ public class WindowManagerService extends IWindowManager.Stub
winAnimator.mEnteringAnimation = true;
if (displayContent.isDefaultDisplay) {
- mPolicy.getInsetHintLw(win.mAttrs, outContentInsets, outStableInsets);
+ mPolicy.getInsetHintLw(win.mAttrs, mRotation, outContentInsets, outStableInsets,
+ outOutsets);
} else {
outContentInsets.setEmpty();
outStableInsets.setEmpty();
@@ -9627,6 +9629,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (w.mContentInsetsChanged
|| w.mVisibleInsetsChanged
|| winAnimator.mSurfaceResized
+ || w.mOutsetsChanged
|| configChanged) {
if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
Slog.v(TAG, "Resize reasons for w=" + w + ": "
@@ -9636,6 +9639,8 @@ public class WindowManagerService extends IWindowManager.Stub
+ " " + w.mVisibleInsets.toShortString()
+ " stableInsetsChanged=" + w.mStableInsetsChanged
+ " " + w.mStableInsets.toShortString()
+ + " outsetsChanged=" + w.mOutsetsChanged
+ + " " + w.mOutsets.toShortString()
+ " surfaceResized=" + winAnimator.mSurfaceResized
+ " configChanged=" + configChanged);
}
@@ -9937,7 +9942,7 @@ public class WindowManagerService extends IWindowManager.Stub
for (i = windows.size() - 1; i >= 0; i--) {
WindowState w = windows.get(i);
if (w.mHasSurface) {
- mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs);
+ mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs, w.mAttachedWindow);
}
}
displayContent.pendingLayoutChanges |= mPolicy.finishPostLayoutPolicyLw();
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
index 3b9cc9d..e257e89 100644
--- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -48,9 +48,9 @@ namespace android
static bool wakeup_init = false;
static sem_t wakeup_sem;
-static void wakeup_callback(void)
+static void wakeup_callback(bool success)
{
- ALOGV("In wakeup_callback");
+ ALOGV("In wakeup_callback: %s", success ? "resumed from suspend" : "suspend aborted");
int ret = sem_post(&wakeup_sem);
if (ret < 0) {
char buf[80];
@@ -59,10 +59,9 @@ static void wakeup_callback(void)
}
}
-static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jintArray outIrqs,
- jobjectArray outReasons)
+static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobjectArray outReasons)
{
- if (outIrqs == NULL || outReasons == NULL) {
+ if (outReasons == NULL) {
jniThrowException(env, "java/lang/NullPointerException", "null argument");
return -1;
}
@@ -100,32 +99,47 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jintArray outIrqs,
return -1;
}
- int numOut = env->GetArrayLength(outIrqs);
- ScopedIntArrayRW irqs(env, outIrqs);
-
- ALOGV("Reading up to %d wakeup reasons", numOut);
+ ALOGV("Reading wakeup reasons");
char mergedreason[MAX_REASON_SIZE];
char* mergedreasonpos = mergedreason;
int remainreasonlen = MAX_REASON_SIZE;
- int firstirq = 0;
char reasonline[128];
int i = 0;
- while (fgets(reasonline, sizeof(reasonline), fp) != NULL && i < numOut) {
+ while (fgets(reasonline, sizeof(reasonline), fp) != NULL) {
char* pos = reasonline;
char* endPos;
- // First field is the index.
+ int len;
+ // First field is the index or 'Abort'.
int irq = (int)strtol(pos, &endPos, 10);
- if (pos == endPos) {
- // Ooops.
- ALOGE("Bad reason line: %s", reasonline);
- continue;
+ if (pos != endPos) {
+ // Write the irq number to the merged reason string.
+ len = snprintf(mergedreasonpos, remainreasonlen, i == 0 ? "%d" : ":%d", irq);
+ } else {
+ // The first field is not an irq, it may be the word Abort.
+ const size_t abortPrefixLen = strlen("Abort:");
+ if (strncmp(pos, "Abort:", abortPrefixLen) != 0) {
+ // Ooops.
+ ALOGE("Bad reason line: %s", reasonline);
+ continue;
+ }
+
+ // Write 'Abort' to the merged reason string.
+ len = snprintf(mergedreasonpos, remainreasonlen, i == 0 ? "Abort" : ":Abort");
+ endPos = pos + abortPrefixLen;
}
pos = endPos;
+
+ if (len >= 0 && len < remainreasonlen) {
+ mergedreasonpos += len;
+ remainreasonlen -= len;
+ }
+
// Skip whitespace; rest of the buffer is the reason string.
while (*pos == ' ') {
pos++;
}
+
// Chop newline at end.
char* endpos = pos;
while (*endpos != 0) {
@@ -135,38 +149,17 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jintArray outIrqs,
}
endpos++;
}
- // For now we are not separating out the first irq.
- // This is because in practice there are always multiple
- // lines of wakeup reasons, so it is better to just treat
- // them all together as a single string.
- if (false && i == 0) {
- firstirq = irq;
- } else {
- int len = snprintf(mergedreasonpos, remainreasonlen,
- i == 0 ? "%d" : ":%d", irq);
- if (len >= 0 && len < remainreasonlen) {
- mergedreasonpos += len;
- remainreasonlen -= len;
- }
- }
- int len = snprintf(mergedreasonpos, remainreasonlen, ":%s", pos);
+
+ len = snprintf(mergedreasonpos, remainreasonlen, ":%s", pos);
if (len >= 0 && len < remainreasonlen) {
mergedreasonpos += len;
remainreasonlen -= len;
}
- // For now it is better to combine all of these in to one entry in the
- // battery history. In the future, it might be nice to figure out a way
- // to efficiently store multiple lines as a single entry in the history.
- //irqs[i] = irq;
- //ScopedLocalRef<jstring> reasonString(env, env->NewStringUTF(pos));
- //env->SetObjectArrayElement(outReasons, i, reasonString.get());
- //ALOGV("Wakeup reason #%d: irw %d reason %s", i, irq, pos);
i++;
}
ALOGV("Got %d reasons", i);
if (i > 0) {
- irqs[0] = firstirq;
*mergedreasonpos = 0;
ScopedLocalRef<jstring> reasonString(env, env->NewStringUTF(mergedreason));
env->SetObjectArrayElement(outReasons, 0, reasonString.get());
@@ -182,7 +175,7 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jintArray outIrqs,
}
static JNINativeMethod method_table[] = {
- { "nativeWaitWakeup", "([I[Ljava/lang/String;)I", (void*)nativeWaitWakeup },
+ { "nativeWaitWakeup", "([Ljava/lang/String;)I", (void*)nativeWaitWakeup },
};
int register_android_server_BatteryStatsService(JNIEnv *env)
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 491b412..5040bd0 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -85,6 +85,7 @@ import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.storage.StorageManager;
import android.provider.ContactsContract.QuickContact;
import android.provider.ContactsInternal;
import android.provider.Settings;
@@ -108,7 +109,6 @@ import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import com.android.internal.R;
-import com.android.internal.os.storage.ExternalStorageFormatter;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
@@ -225,6 +225,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private static final Set<String> SECURE_SETTINGS_WHITELIST;
private static final Set<String> SECURE_SETTINGS_DEVICEOWNER_WHITELIST;
private static final Set<String> GLOBAL_SETTINGS_WHITELIST;
+ private static final Set<String> GLOBAL_SETTINGS_DEPRECATED;
static {
SECURE_SETTINGS_WHITELIST = new HashSet();
SECURE_SETTINGS_WHITELIST.add(Settings.Secure.DEFAULT_INPUT_METHOD);
@@ -240,13 +241,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.AUTO_TIME);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.AUTO_TIME_ZONE);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.DATA_ROAMING);
- GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
- GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.MODE_RINGER);
- GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.NETWORK_PREFERENCE);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.USB_MASS_STORAGE_ENABLED);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_SLEEP_POLICY);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN);
+
+ GLOBAL_SETTINGS_DEPRECATED = new HashSet();
+ GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.BLUETOOTH_ON);
+ GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
+ GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.MODE_RINGER);
+ GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.NETWORK_PREFERENCE);
+ GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.WIFI_ON);
}
// Keyguard features that when set of a profile will affect the profiles
@@ -385,6 +390,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
} else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)
&& !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
handlePackagesChanged(intent.getData().getSchemeSpecificPart(), userHandle);
+ } else if (Intent.ACTION_MANAGED_PROFILE_ADDED.equals(action)) {
+ clearWipeProfileNotification();
}
}
};
@@ -1062,6 +1069,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
filter.addDataScheme("package");
context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
+ filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
+ context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
LocalServices.addService(DevicePolicyManagerInternal.class, mLocalService);
}
@@ -3307,25 +3317,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
private void wipeDataLocked(boolean wipeExtRequested, String reason) {
- // TODO: wipe all public volumes on device
-
- // If the SD card is encrypted and non-removable, we have to force a wipe.
- boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted();
-
- // Note: we can only do the wipe via ExternalStorageFormatter if the volume is not emulated.
- if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) {
- Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
- intent.putExtra(ExternalStorageFormatter.EXTRA_ALWAYS_RESET, true);
- intent.putExtra(Intent.EXTRA_REASON, reason);
- intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
- mWakeLock.acquire(10000);
- mContext.startService(intent);
- } else {
- try {
- RecoverySystem.rebootWipeUserData(mContext, reason);
- } catch (IOException | SecurityException e) {
- Slog.w(LOG_TAG, "Failed requesting data wipe", e);
- }
+ if (wipeExtRequested) {
+ StorageManager sm = (StorageManager) mContext.getSystemService(
+ Context.STORAGE_SERVICE);
+ sm.wipeAdoptableDisks();
+ }
+ try {
+ RecoverySystem.rebootWipeUserData(mContext, reason);
+ } catch (IOException | SecurityException e) {
+ Slog.w(LOG_TAG, "Failed requesting data wipe", e);
}
}
@@ -3414,6 +3414,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
getNotificationManager().notify(PROFILE_WIPED_NOTIFICATION_ID, notification);
}
+ private void clearWipeProfileNotification() {
+ getNotificationManager().cancel(PROFILE_WIPED_NOTIFICATION_ID);
+ }
+
@Override
public void getRemoveWarning(ComponentName comp, final RemoteCallback result, int userHandle) {
if (!mHasFeature) {
@@ -5964,14 +5968,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
synchronized (this) {
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+ // Some settings are no supported any more. However we do not want to throw a
+ // SecurityException to avoid breaking apps.
+ if (GLOBAL_SETTINGS_DEPRECATED.contains(setting)) {
+ Log.i(LOG_TAG, "Global setting no longer supported: " + setting);
+ return;
+ }
+
if (!GLOBAL_SETTINGS_WHITELIST.contains(setting)) {
- // BLUETOOTH_ON and WIFI_ON used to be supported but not any more. We do not want to
- // throw a SecurityException not to break apps.
- if (!Settings.Global.BLUETOOTH_ON.equals(setting)
- && !Settings.Global.WIFI_ON.equals(setting)) {
- throw new SecurityException(String.format(
- "Permission denial: device owners cannot update %1$s", setting));
- }
+ throw new SecurityException(String.format(
+ "Permission denial: device owners cannot update %1$s", setting));
}
if (Settings.Global.STAY_ON_WHILE_PLUGGED_IN.equals(setting)) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 76226b4..014527b 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -21,7 +21,6 @@ import android.app.ActivityThread;
import android.app.IAlarmManager;
import android.app.INotificationManager;
import android.app.usage.UsageStatsManagerInternal;
-import android.bluetooth.BluetoothAdapter;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -401,7 +400,6 @@ public final class SystemServer {
NetworkScoreService networkScore = null;
NsdService serviceDiscovery= null;
WindowManagerService wm = null;
- BluetoothManagerService bluetooth = null;
UsbService usb = null;
SerialService serial = null;
NetworkTimeUpdateService networkTimeUpdater = null;
@@ -508,9 +506,8 @@ public final class SystemServer {
} else if (disableBluetooth) {
Slog.i(TAG, "Bluetooth Service disabled by config");
} else {
- Slog.i(TAG, "Bluetooth Manager Service");
- bluetooth = new BluetoothManagerService(context);
- ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth);
+ Slog.i(TAG, "Bluetooth Service");
+ mSystemServiceManager.startService(BluetoothService.class);
}
} catch (RuntimeException e) {
Slog.e("System", "******************************************");
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index b68abab..61ae1c0 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -433,6 +433,11 @@ public class VoiceInteractionManagerService extends SystemService {
+ " user=" + userHandle);
}
+ void resetCurAssistant(int userHandle) {
+ Settings.Secure.putStringForUser(mContext.getContentResolver(),
+ Settings.Secure.ASSISTANT, null, userHandle);
+ }
+
@Override
public void showSession(IVoiceInteractionService service, Bundle args, int flags) {
synchronized (this) {
@@ -540,6 +545,24 @@ public class VoiceInteractionManagerService extends SystemService {
}
@Override
+ public void closeSystemDialogs(IBinder token) {
+ synchronized (this) {
+ if (mImpl == null) {
+ Slog.w(TAG, "closeSystemDialogs without running voice interaction service");
+ return;
+ }
+ final int callingPid = Binder.getCallingPid();
+ final int callingUid = Binder.getCallingUid();
+ final long caller = Binder.clearCallingIdentity();
+ try {
+ mImpl.closeSystemDialogsLocked(callingPid, callingUid, token);
+ } finally {
+ Binder.restoreCallingIdentity(caller);
+ }
+ }
+ }
+
+ @Override
public void finish(IBinder token) {
synchronized (this) {
if (mImpl == null) {
@@ -897,6 +920,7 @@ public class VoiceInteractionManagerService extends SystemService {
}
setCurInteractor(null, userHandle);
setCurRecognizer(null, userHandle);
+ resetCurAssistant(userHandle);
initForUser(userHandle);
switchImplementationIfNeededLocked(true);
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index af0ddbe..e5faf4d 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -48,6 +48,8 @@ import java.io.PrintWriter;
class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConnection.Callback {
final static String TAG = "VoiceInteractionServiceManager";
+ final static String CLOSE_REASON_VOICE_INTERACTION = "voiceinteraction";
+
final boolean mValid;
final Context mContext;
@@ -68,11 +70,14 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
- synchronized (mLock) {
- if (mActiveSession != null && mActiveSession.mSession != null) {
- try {
- mActiveSession.mSession.closeSystemDialogs();
- } catch (RemoteException e) {
+ String reason = intent.getStringExtra("reason");
+ if (!CLOSE_REASON_VOICE_INTERACTION.equals(reason)) {
+ synchronized (mLock) {
+ if (mActiveSession != null && mActiveSession.mSession != null) {
+ try {
+ mActiveSession.mSession.closeSystemDialogs();
+ } catch (RemoteException e) {
+ }
}
}
}
@@ -196,6 +201,18 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
}
}
+ public void closeSystemDialogsLocked(int callingPid, int callingUid, IBinder token) {
+ try {
+ if (mActiveSession == null || token != mActiveSession.mToken) {
+ Slog.w(TAG, "closeSystemDialogs does not match active session");
+ return;
+ }
+ mAm.closeSystemDialogs(CLOSE_REASON_VOICE_INTERACTION);
+ } catch (RemoteException e) {
+ throw new IllegalStateException("Unexpected remote error", e);
+ }
+ }
+
public void finishLocked(IBinder token) {
if (mActiveSession == null || token != mActiveSession.mToken) {
Slog.w(TAG, "finish does not match active session");
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index cc6a9c5..bd043ac 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -193,8 +193,17 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
new UserHandle(mUser));
}
mShown = true;
- boolean allDataEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
- Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, mUser) != 0;
+ boolean isScreenCaptureAllowed = true;
+ try {
+ isScreenCaptureAllowed = mAm.isScreenCaptureAllowedOnCurrentActivity();
+ } catch (RemoteException e) {
+ }
+ boolean structureEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, mUser) != 0
+ && isScreenCaptureAllowed;
+ boolean screenshotEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_SCREENSHOT_ENABLED, 1, mUser) != 0
+ && isScreenCaptureAllowed;
mShowArgs = args;
mShowFlags = flags;
mHaveAssistData = false;
@@ -202,7 +211,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
if ((flags& VoiceInteractionSession.SHOW_WITH_ASSIST) != 0) {
if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ASSIST_STRUCTURE, mCallingUid,
mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED
- && allDataEnabled) {
+ && structureEnabled) {
try {
needDisclosure = true;
mAm.requestAssistContextExtras(ActivityManager.ASSIST_CONTEXT_FULL,
@@ -220,7 +229,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
if ((flags& VoiceInteractionSession.SHOW_WITH_SCREENSHOT) != 0) {
if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ASSIST_SCREENSHOT, mCallingUid,
mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED
- && allDataEnabled) {
+ && screenshotEnabled) {
try {
needDisclosure = true;
mIWindowManager.requestAssistScreenshot(mScreenshotReceiver);
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 6055211..f304d1d 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -34,13 +34,13 @@ import android.view.Surface;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
- * Represents a connection to a remote endpoint that carries voice traffic.
+ * Represents a phone call or connection to a remote endpoint that carries voice and/or video
+ * traffic.
* <p>
* Implementations create a custom subclass of {@code Connection} and return it to the framework
* as the return value of
@@ -53,21 +53,52 @@ import java.util.concurrent.ConcurrentHashMap;
*/
public abstract class Connection extends Conferenceable {
+ /**
+ * The connection is initializing. This is generally the first state for a {@code Connection}
+ * returned by a {@link ConnectionService}.
+ */
public static final int STATE_INITIALIZING = 0;
+ /**
+ * The connection is new and not connected.
+ */
public static final int STATE_NEW = 1;
+ /**
+ * An incoming connection is in the ringing state. During this state, the user's ringer or
+ * vibration feature will be activated.
+ */
public static final int STATE_RINGING = 2;
+ /**
+ * An outgoing connection is in the dialing state. In this state the other party has not yet
+ * answered the call and the user traditionally hears a ringback tone.
+ */
public static final int STATE_DIALING = 3;
+ /**
+ * A connection is active. Both parties are connected to the call and can actively communicate.
+ */
public static final int STATE_ACTIVE = 4;
+ /**
+ * A connection is on hold.
+ */
public static final int STATE_HOLDING = 5;
+ /**
+ * A connection has been disconnected. This is the final state once the user has been
+ * disconnected from a call either locally, remotely or by an error in the service.
+ */
public static final int STATE_DISCONNECTED = 6;
- /** Connection can currently be put on hold or unheld. */
+ /**
+ * Connection can currently be put on hold or unheld. This is distinct from
+ * {@link #CAPABILITY_SUPPORT_HOLD} in that although a connection may support 'hold' most times,
+ * it does not at the moment support the function. This can be true while the call is in the
+ * state {@link #STATE_DIALING}, for example. During this condition, an in-call UI may
+ * display a disabled 'hold' button.
+ */
public static final int CAPABILITY_HOLD = 0x00000001;
/** Connection supports the hold feature. */
@@ -195,8 +226,30 @@ public abstract class Connection extends Conferenceable {
*/
public static final int CAPABILITY_CAN_PAUSE_VIDEO = 0x00100000;
+ /**
+ * For a conference, indicates the conference will not have child connections.
+ * <p>
+ * An example of a conference with child connections is a GSM conference call, where the radio
+ * retains connections to the individual participants of the conference. Another example is an
+ * IMS conference call where conference event package functionality is supported; in this case
+ * the conference server ensures the radio is aware of the participants in the conference, which
+ * are represented by child connections.
+ * <p>
+ * An example of a conference with no child connections is an IMS conference call with no
+ * conference event package support. Such a conference is represented by the radio as a single
+ * connection to the IMS conference server.
+ * <p>
+ * Indicating whether a conference has children or not is important to help user interfaces
+ * visually represent a conference. A conference with no children, for example, will have the
+ * conference connection shown in the list of calls on a Bluetooth device, where if the
+ * conference has children, only the children will be shown in the list of calls on a Bluetooth
+ * device.
+ * @hide
+ */
+ public static final int CAPABILITY_CONFERENCE_HAS_NO_CHILDREN = 0x00200000;
+
//**********************************************************************************************
- // Next CAPABILITY value: 0x00200000
+ // Next CAPABILITY value: 0x00400000
//**********************************************************************************************
// Flag controlling whether PII is emitted into the logs
@@ -309,6 +362,9 @@ public abstract class Connection extends Conferenceable {
if (can(capabilities, CAPABILITY_CAN_PAUSE_VIDEO)) {
builder.append(" CAPABILITY_CAN_PAUSE_VIDEO");
}
+ if (can(capabilities, CAPABILITY_CONFERENCE_HAS_NO_CHILDREN)) {
+ builder.append(" CAPABILITY_SINGLE_PARTY_CONFERENCE");
+ }
builder.append("]");
return builder.toString();
}
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 1e8ae88..d2e7a74 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -41,8 +41,8 @@ import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/**
- * {@code ConnectionService} is an abstract service that should be implemented by any app which can
- * make phone calls and want those calls to be integrated into the built-in phone app.
+ * An abstract service that should be implemented by any apps which can make phone calls (VoIP or
+ * otherwise) and want those calls to be integrated into the built-in phone app.
* Once implemented, the {@code ConnectionService} needs two additional steps before it will be
* integrated into the phone app:
* <p>
@@ -62,7 +62,7 @@ import java.util.concurrent.ConcurrentHashMap;
* <br/>
* See {@link PhoneAccount} and {@link TelecomManager#registerPhoneAccount} for more information.
* <p>
- * Once registered and enabled by the user in the dialer settings, telecom will bind to a
+ * Once registered and enabled by the user in the phone app settings, telecom will bind to a
* {@code ConnectionService} implementation when it wants that {@code ConnectionService} to place
* a call or the service has indicated that is has an incoming call through
* {@link TelecomManager#addNewIncomingCall}. The {@code ConnectionService} can then expect a call
diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java
index 0f8ac63..19c613d 100644
--- a/telecomm/java/android/telecom/InCallService.java
+++ b/telecomm/java/android/telecom/InCallService.java
@@ -248,7 +248,7 @@ public abstract class InCallService extends Service {
}
/**
- * Obtains the current list of {@code Call}s to be displayed by this in-call experience.
+ * Obtains the current list of {@code Call}s to be displayed by this in-call service.
*
* @return A list of the relevant {@code Call}s.
*/
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index a25d327..df6fa2e 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -412,7 +412,7 @@ public final class PhoneAccount implements Parcelable {
* bit mask.
*
* @param capability The capabilities to check.
- * @return {@code True} if the phone account has the capability.
+ * @return {@code true} if the phone account has the capability.
*/
public boolean hasCapabilities(int capability) {
return (mCapabilities & capability) == capability;
@@ -455,9 +455,10 @@ public final class PhoneAccount implements Parcelable {
}
/**
- * Indicates whether the user has enabled this phone account or not {@code PhoneAccounts}.
+ * Indicates whether the user has enabled this {@code PhoneAccount} or not. This value is only
+ * populated for {@code PhoneAccount}s returned by {@link TelecomManager#getPhoneAccount}.
*
- * @return The {@code true} if the account is enabled by the user, {@code false} otherwise.
+ * @return {@code true} if the account is enabled by the user, {@code false} otherwise.
*/
public boolean isEnabled() {
return mIsEnabled;
@@ -468,7 +469,7 @@ public final class PhoneAccount implements Parcelable {
* scheme.
*
* @param uriScheme The URI scheme to check.
- * @return {@code True} if the {@code PhoneAccount} supports calls to/from addresses with the
+ * @return {@code true} if the {@code PhoneAccount} supports calls to/from addresses with the
* specified URI scheme.
*/
public boolean supportsUriScheme(String uriScheme) {
diff --git a/telecomm/java/android/telecom/RemoteConference.java b/telecomm/java/android/telecom/RemoteConference.java
index c2261c3..ae5cd46 100644
--- a/telecomm/java/android/telecom/RemoteConference.java
+++ b/telecomm/java/android/telecom/RemoteConference.java
@@ -32,25 +32,90 @@ import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
/**
- * A conference provided to a {@link ConnectionService} by another {@code ConnectionService}
- * running in a different process.
+ * A conference provided to a {@link ConnectionService} by another {@code ConnectionService} through
+ * {@link ConnectionService#conferenceRemoteConnections}. Once created, a {@code RemoteConference}
+ * can be used to control the conference call or monitor changes through
+ * {@link RemoteConnection.Callback}.
*
* @see ConnectionService#onRemoteConferenceAdded
*/
public final class RemoteConference {
+ /**
+ * Callback base class for {@link RemoteConference}.
+ */
public abstract static class Callback {
+ /**
+ * Invoked when the state of this {@code RemoteConferece} has changed. See
+ * {@link #getState()}.
+ *
+ * @param conference The {@code RemoteConference} invoking this method.
+ * @param oldState The previous state of the {@code RemoteConference}.
+ * @param newState The new state of the {@code RemoteConference}.
+ */
public void onStateChanged(RemoteConference conference, int oldState, int newState) {}
+
+ /**
+ * Invoked when this {@code RemoteConference} is disconnected.
+ *
+ * @param conference The {@code RemoteConference} invoking this method.
+ * @param disconnectCause The ({@see DisconnectCause}) associated with this failed
+ * conference.
+ */
public void onDisconnected(RemoteConference conference, DisconnectCause disconnectCause) {}
+
+ /**
+ * Invoked when a {@link RemoteConnection} is added to the conference call.
+ *
+ * @param conference The {@code RemoteConference} invoking this method.
+ * @param connection The {@link RemoteConnection} being added.
+ */
public void onConnectionAdded(RemoteConference conference, RemoteConnection connection) {}
+
+ /**
+ * Invoked when a {@link RemoteConnection} is removed from the conference call.
+ *
+ * @param conference The {@code RemoteConference} invoking this method.
+ * @param connection The {@link RemoteConnection} being removed.
+ */
public void onConnectionRemoved(RemoteConference conference, RemoteConnection connection) {}
+
+ /**
+ * Indicates that the call capabilities of this {@code RemoteConference} have changed.
+ * See {@link #getConnectionCapabilities()}.
+ *
+ * @param conference The {@code RemoteConference} invoking this method.
+ * @param connectionCapabilities The new capabilities of the {@code RemoteConference}.
+ */
public void onConnectionCapabilitiesChanged(
RemoteConference conference,
int connectionCapabilities) {}
+
+ /**
+ * Invoked when the set of {@link RemoteConnection}s which can be added to this conference
+ * call have changed.
+ *
+ * @param conference The {@code RemoteConference} invoking this method.
+ * @param conferenceableConnections The list of conferenceable {@link RemoteConnection}s.
+ */
public void onConferenceableConnectionsChanged(
RemoteConference conference,
List<RemoteConnection> conferenceableConnections) {}
+
+ /**
+ * Indicates that this {@code RemoteConference} has been destroyed. No further requests
+ * should be made to the {@code RemoteConference}, and references to it should be cleared.
+ *
+ * @param conference The {@code RemoteConference} invoking this method.
+ */
public void onDestroyed(RemoteConference conference) {}
+
+ /**
+ * Handles changes to the {@code RemoteConference} extras.
+ *
+ * @param conference The {@code RemoteConference} invoking this method.
+ * @param extras The extras containing other information associated with the conference.
+ */
public void onExtrasChanged(RemoteConference conference, @Nullable Bundle extras) {}
}
diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java
index 8f7b82f..f960959 100644
--- a/telecomm/java/android/telecom/RemoteConnection.java
+++ b/telecomm/java/android/telecom/RemoteConnection.java
@@ -45,6 +45,9 @@ import java.util.concurrent.ConcurrentHashMap;
*/
public final class RemoteConnection {
+ /**
+ * Callback base class for {@link RemoteConnection}.
+ */
public static abstract class Callback {
/**
* Invoked when the state of this {@code RemoteConnection} has changed. See
@@ -200,7 +203,7 @@ public final class RemoteConnection {
RemoteConference conference) {}
/**
- * Handles changes to the {@code RemoteConference} extras.
+ * Handles changes to the {@code RemoteConnection} extras.
*
* @param connection The {@code RemoteConnection} invoking this method.
* @param extras The extras containing other information associated with the connection.
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 11f206a..a30e1c0 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -67,11 +67,19 @@ public class TelecomManager {
public static final String ACTION_NEW_UNKNOWN_CALL = "android.telecom.action.NEW_UNKNOWN_CALL";
/**
- * The {@link android.content.Intent} action used to configure a
- * {@link android.telecom.ConnectionService}.
- */
- public static final String ACTION_CONNECTION_SERVICE_CONFIGURE =
- "android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
+ * An {@link android.content.Intent} action sent by the telecom framework to start a
+ * configuration dialog for a registered {@link PhoneAccount}. There is no default dialog
+ * and each app that registers a {@link PhoneAccount} should provide one if desired.
+ * <p>
+ * A user can access the list of enabled {@link android.telecom.PhoneAccount}s through the Phone
+ * app's settings menu. For each entry, the settings app will add a click action. When
+ * triggered, the click-action will start this intent along with the extra
+ * {@link #EXTRA_PHONE_ACCOUNT_HANDLE} to indicate the {@link PhoneAccount} to configure. If the
+ * {@link PhoneAccount} package does not register an {@link android.app.Activity} for this
+ * intent, then it will not be sent.
+ */
+ public static final String ACTION_CONFIGURE_PHONE_ACCOUNT =
+ "android.telecom.action.CONFIGURE_PHONE_ACCOUNT";
/**
* The {@link android.content.Intent} action used to show the call accessibility settings page.
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 3fcd7d9..d18b86a 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -2080,14 +2080,35 @@ public class PhoneNumberUtils
* @hide
*/
public static boolean isVoiceMailNumber(int subId, String number) {
- String vmNumber;
+ return isVoiceMailNumber(null, subId, number);
+ }
+ /**
+ * isVoiceMailNumber: checks a given number against the voicemail
+ * number provided by the RIL and SIM card. The caller must have
+ * the READ_PHONE_STATE credential.
+ *
+ * @param context a non-null {@link Context}.
+ * @param subId the subscription id of the SIM.
+ * @param number the number to look up.
+ * @return true if the number is in the list of voicemail. False
+ * otherwise, including if the caller does not have the permission
+ * to read the VM number.
+ * @hide
+ */
+ public static boolean isVoiceMailNumber(Context context, int subId, String number) {
+ String vmNumber;
try {
- vmNumber = TelephonyManager.getDefault().getVoiceMailNumber(subId);
+ final TelephonyManager tm;
+ if (context == null) {
+ tm = TelephonyManager.getDefault();
+ } else {
+ tm = TelephonyManager.from(context);
+ }
+ vmNumber = tm.getVoiceMailNumber(subId);
} catch (SecurityException ex) {
return false;
}
-
// Strip the separators from the number before comparing it
// to the list.
number = extractNetworkPortionAlt(number);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index a2bd74b..68f71f2 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -20,6 +20,7 @@ import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.app.ActivityThread;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -133,6 +134,16 @@ public class TelephonyManager {
return sInstance;
}
+ private String getOpPackageName() {
+ // For legacy reasons the TelephonyManager has API for getting
+ // a static instance with no context set preventing us from
+ // getting the op package name. As a workaround we do a best
+ // effort and get the context from the current activity thread.
+ if (mContext != null) {
+ return mContext.getOpPackageName();
+ }
+ return ActivityThread.currentOpPackageName();
+ }
/**
* Returns the multi SIM variant
@@ -891,16 +902,17 @@ public class TelephonyManager {
}
/**
- * Returns the neighboring cell information of the device. The getAllCellInfo is preferred
- * and use this only if getAllCellInfo return nulls or an empty list.
- *<p>
- * In the future this call will be deprecated.
- *<p>
+ * Returns the neighboring cell information of the device.
+ *
* @return List of NeighboringCellInfo or null if info unavailable.
*
* <p>Requires Permission:
* (@link android.Manifest.permission#ACCESS_COARSE_UPDATES}
+ *
+ * @deprecated Use (@link getAllCellInfo} which returns a superset of the information
+ * from NeighboringCellInfo.
*/
+ @Deprecated
public List<NeighboringCellInfo> getNeighboringCellInfo() {
try {
ITelephony telephony = getITelephony();
@@ -2010,6 +2022,8 @@ public class TelephonyManager {
* <p>
* Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ * <p>
+ * The default SMS app can also use this.
*/
public String getLine1Number() {
return getLine1NumberForSubscriber(getDefaultSubscription());
@@ -2021,6 +2035,8 @@ public class TelephonyManager {
* <p>
* Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ * <p>
+ * The default SMS app can also use this.
*
* @param subId whose phone number for line 1 is returned
*/
@@ -2123,7 +2139,7 @@ public class TelephonyManager {
ITelephony telephony = getITelephony();
if (telephony != null)
alphaTag = telephony.getLine1AlphaTagForDisplay(subId,
- mContext.getOpPackageName());
+ getOpPackageName());
} catch (RemoteException ex) {
} catch (NullPointerException ex) {
}
@@ -2134,7 +2150,7 @@ public class TelephonyManager {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- return info.getLine1AlphaTagForSubscriber(subId, mContext.getOpPackageName());
+ return info.getLine1AlphaTagForSubscriber(subId, getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -2155,7 +2171,7 @@ public class TelephonyManager {
try {
ITelephony telephony = getITelephony();
if (telephony != null)
- return telephony.getMergedSubscriberIds(mContext.getOpPackageName());
+ return telephony.getMergedSubscriberIds(getOpPackageName());
} catch (RemoteException ex) {
} catch (NullPointerException ex) {
}
@@ -2190,7 +2206,7 @@ public class TelephonyManager {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- return info.getMsisdnForSubscriber(subId, mContext.getOpPackageName());
+ return info.getMsisdnForSubscriber(subId, getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -2223,7 +2239,7 @@ public class TelephonyManager {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- return info.getVoiceMailNumberForSubscriber(subId, mContext.getOpPackageName());
+ return info.getVoiceMailNumberForSubscriber(subId, getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -2362,7 +2378,7 @@ public class TelephonyManager {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- return info.getVoiceMailAlphaTagForSubscriber(subId, mContext.getOpPackageName());
+ return info.getVoiceMailAlphaTagForSubscriber(subId, getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -2614,7 +2630,7 @@ public class TelephonyManager {
if (mContext == null) return;
try {
Boolean notifyNow = (getITelephony() != null);
- sRegistry.listenForSubscriber(listener.mSubId, mContext.getOpPackageName(),
+ sRegistry.listenForSubscriber(listener.mSubId, getOpPackageName(),
listener.callback, events, notifyNow);
} catch (RemoteException ex) {
// system process dead
@@ -2770,7 +2786,7 @@ public class TelephonyManager {
ITelephony telephony = getITelephony();
if (telephony == null)
return null;
- return telephony.getAllCellInfo(mContext.getOpPackageName());
+ return telephony.getAllCellInfo(getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -3382,7 +3398,7 @@ public class TelephonyManager {
ITelephony telephony = getITelephony();
if (telephony == null)
return new String[0];
- return telephony.getPcscfAddress(apnType, mContext.getOpPackageName());
+ return telephony.getPcscfAddress(apnType, getOpPackageName());
} catch (RemoteException e) {
return new String[0];
}
@@ -3805,7 +3821,7 @@ public class TelephonyManager {
@SystemApi
public void silenceRinger() {
try {
- getTelecomService().silenceRinger(mContext.getOpPackageName());
+ getTelecomService().silenceRinger(getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#silenceRinger", e);
}
@@ -3869,7 +3885,7 @@ public class TelephonyManager {
try {
ITelephony telephony = getITelephony();
if (telephony != null)
- return telephony.isSimPinEnabled(mContext.getOpPackageName());
+ return telephony.isSimPinEnabled(getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelephony#isSimPinEnabled", e);
}
@@ -4136,7 +4152,7 @@ public class TelephonyManager {
try {
ITelephony telephony = getITelephony();
if (telephony != null)
- return telephony.isVideoCallingEnabled(mContext.getOpPackageName());
+ return telephony.isVideoCallingEnabled(getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelephony#isVideoCallingEnabled", e);
}
@@ -4156,6 +4172,8 @@ public class TelephonyManager {
}
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelephony#canChangeDtmfToneLength", e);
+ } catch (SecurityException e) {
+ Log.w(TAG, "Permission error calling ITelephony#canChangeDtmfToneLength", e);
}
return false;
}
diff --git a/telephony/java/com/android/ims/ImsCallProfile.java b/telephony/java/com/android/ims/ImsCallProfile.java
index b0b95f6..2c4354b 100644
--- a/telephony/java/com/android/ims/ImsCallProfile.java
+++ b/telephony/java/com/android/ims/ImsCallProfile.java
@@ -143,6 +143,8 @@ public class ImsCallProfile implements Parcelable {
public static final int OIR_DEFAULT = 0; // "user subscription default value"
public static final int OIR_PRESENTATION_RESTRICTED = 1;
public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2;
+ public static final int OIR_PRESENTATION_UNKNOWN = 3;
+ public static final int OIR_PRESENTATION_PAYPHONE = 4;
/**
* Values for EXTRA_DIALSTRING
@@ -373,6 +375,10 @@ public class ImsCallProfile implements Parcelable {
return ImsCallProfile.OIR_PRESENTATION_RESTRICTED;
case PhoneConstants.PRESENTATION_ALLOWED:
return ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED;
+ case PhoneConstants.PRESENTATION_PAYPHONE:
+ return ImsCallProfile.OIR_PRESENTATION_PAYPHONE;
+ case PhoneConstants.PRESENTATION_UNKNOWN:
+ return ImsCallProfile.OIR_PRESENTATION_UNKNOWN;
default:
return ImsCallProfile.OIR_DEFAULT;
}
@@ -389,6 +395,10 @@ public class ImsCallProfile implements Parcelable {
return PhoneConstants.PRESENTATION_RESTRICTED;
case ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED:
return PhoneConstants.PRESENTATION_ALLOWED;
+ case ImsCallProfile.OIR_PRESENTATION_PAYPHONE:
+ return PhoneConstants.PRESENTATION_PAYPHONE;
+ case ImsCallProfile.OIR_PRESENTATION_UNKNOWN:
+ return PhoneConstants.PRESENTATION_UNKNOWN;
default:
return PhoneConstants.PRESENTATION_UNKNOWN;
}
diff --git a/telephony/java/com/android/internal/telephony/CellNetworkScanResult.java b/telephony/java/com/android/internal/telephony/CellNetworkScanResult.java
index c708c14..5a6bd1d 100644
--- a/telephony/java/com/android/internal/telephony/CellNetworkScanResult.java
+++ b/telephony/java/com/android/internal/telephony/CellNetworkScanResult.java
@@ -88,6 +88,7 @@ public class CellNetworkScanResult implements Parcelable {
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mStatus);
if (mOperators != null && mOperators.size() > 0) {
+ out.writeInt(mOperators.size());
for (OperatorInfo network : mOperators) {
network.writeToParcel(out, flags);
}
diff --git a/tests/ActivityTests/AndroidManifest.xml b/tests/ActivityTests/AndroidManifest.xml
index dae7cc5..73cb432 100644
--- a/tests/ActivityTests/AndroidManifest.xml
+++ b/tests/ActivityTests/AndroidManifest.xml
@@ -24,6 +24,7 @@
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
<uses-permission android:name="android.permission.MANAGE_USERS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+ <uses-sdk android:targetSdkVersion="22" />
<application android:label="ActivityTest">
<activity android:name="ActivityTestMain">
<intent-filter>
diff --git a/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java b/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java
index e4ea0bc..43f1e32 100644
--- a/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java
+++ b/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java
@@ -52,28 +52,23 @@ public class AssistInteractionSession extends VoiceInteractionSession {
}
@Override
- public void onConfirm(Caller caller,
- Request request, CharSequence prompt, Bundle extras) {
-
+ public void onRequestConfirmation(ConfirmationRequest request) {
}
@Override
- public void onPickOption(Caller caller,
- Request request, CharSequence prompt,
- VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) {
-
+ public void onRequestPickOption(PickOptionRequest request) {
}
@Override
- public void onCommand(Caller caller,
- Request request, String command, Bundle extras) {
-
+ public void onRequestCommand(CommandRequest request) {
}
@Override
- public void onCreate(Bundle args) {
- super.onCreate(args);
+ public void onCancelRequest(Request request) {
+ }
+ @Override
+ public void onCreate() {
// Simulate slowness of Assist app
try {
Thread.sleep(1000);
@@ -83,11 +78,6 @@ public class AssistInteractionSession extends VoiceInteractionSession {
}
@Override
- public void onCancel(Request request) {
-
- }
-
- @Override
public View onCreateContentView() {
View v = getLayoutInflater().inflate(R.layout.assist, null);
mScrim = v.findViewById(R.id.scrim);
diff --git a/tests/VoiceInteraction/res/layout/test_interaction.xml b/tests/VoiceInteraction/res/layout/test_interaction.xml
index 6209bd0..d1a7ad5 100644
--- a/tests/VoiceInteraction/res/layout/test_interaction.xml
+++ b/tests/VoiceInteraction/res/layout/test_interaction.xml
@@ -51,6 +51,19 @@
android:text="@string/abortVoice"
/>
+ </LinearLayout>
+
+ <LinearLayout android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:orientation="horizontal">
+
+ <Button android:id="@+id/command"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/commandVoice"
+ />
+
<Button android:id="@+id/pick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
index d44afb0..610f30b 100644
--- a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
+++ b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
@@ -18,6 +18,11 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
+ <ImageView android:id="@+id/full_screenshot"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible"/>
+
<com.android.test.voiceinteraction.AssistVisualizer android:id="@+id/assist_visualizer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
@@ -30,19 +35,29 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
- android:orientation="vertical"
+ android:orientation="horizontal"
android:background="#ffffffff"
android:elevation="8dp"
>
- <Button android:id="@+id/start"
+ <ImageView android:id="@+id/screenshot"
+ android:layout_width="wrap_content"
+ android:layout_height="46dp"
+ android:adjustViewBounds="true" />
+ <View android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+ <Button android:id="@+id/do_tree"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="top|right"
- android:text="@string/start"
- />
- <ImageView android:id="@+id/screenshot"
+ android:text="@string/tree" />
+ <Button android:id="@+id/do_text"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
+ android:layout_height="wrap_content"
+ android:text="@string/text" />
+ <Button android:id="@+id/start"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/start" />
</LinearLayout>
<LinearLayout android:id="@+id/bottom_content"
@@ -58,26 +73,22 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- />
+ android:textAppearance="?android:attr/textAppearanceMedium" />
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="horizontal">
<Button android:id="@+id/confirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/confirm"
- />
+ android:text="@string/confirm" />
<Button android:id="@+id/complete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/complete"
- />
+ android:text="@string/complete" />
<Button android:id="@+id/abort"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/abort"
- />
+ android:text="@string/abort" />
</LinearLayout>
</LinearLayout>
diff --git a/tests/VoiceInteraction/res/values/strings.xml b/tests/VoiceInteraction/res/values/strings.xml
index 6289929..cf660e6 100644
--- a/tests/VoiceInteraction/res/values/strings.xml
+++ b/tests/VoiceInteraction/res/values/strings.xml
@@ -17,11 +17,14 @@
<resources>
<string name="start">Start</string>
+ <string name="tree">Tree</string>
+ <string name="text">Text</string>
<string name="asyncStructure">(Async structure goes here)</string>
<string name="confirm">Confirm</string>
<string name="abort">Abort</string>
<string name="complete">Complete</string>
<string name="abortVoice">Abort Voice</string>
+ <string name="commandVoice">Command</string>
<string name="completeVoice">Complete Voice</string>
<string name="pickVoice">Pick Voice</string>
<string name="cancelVoice">Cancel</string>
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
index 439ace8..339755f 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
@@ -20,6 +20,7 @@ import android.annotation.Nullable;
import android.app.assist.AssistStructure;
import android.content.Context;
import android.graphics.Canvas;
+import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
@@ -31,10 +32,32 @@ import java.util.ArrayList;
public class AssistVisualizer extends View {
static final String TAG = "AssistVisualizer";
+ static class TextEntry {
+ final Rect bounds;
+ final int parentLeft, parentTop;
+ final Matrix matrix;
+ final String className;
+ final CharSequence text;
+
+ TextEntry(AssistStructure.ViewNode node, int parentLeft, int parentTop, Matrix matrix) {
+ int left = parentLeft+node.getLeft();
+ int top = parentTop+node.getTop();
+ bounds = new Rect(left, top, left+node.getWidth(), top+node.getHeight());
+ this.parentLeft = parentLeft;
+ this.parentTop = parentTop;
+ this.matrix = new Matrix(matrix);
+ this.className = node.getClassName();
+ this.text = node.getText() != null ? node.getText() : node.getContentDescription();
+ }
+ }
+
AssistStructure mAssistStructure;
final Paint mFramePaint = new Paint();
- final ArrayList<Rect> mTextRects = new ArrayList<>();
+ final Paint mFrameNoTransformPaint = new Paint();
+ final ArrayList<Matrix> mMatrixStack = new ArrayList<>();
+ final ArrayList<TextEntry> mTextRects = new ArrayList<>();
final int[] mTmpLocation = new int[2];
+ final float[] mTmpMatrixPoint = new float[2];
public AssistVisualizer(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
@@ -42,17 +65,26 @@ public class AssistVisualizer extends View {
mFramePaint.setColor(0xffff0000);
mFramePaint.setStyle(Paint.Style.STROKE);
mFramePaint.setStrokeWidth(0);
+ float density = getResources().getDisplayMetrics().density;
+ mFramePaint.setShadowLayer(density, density, density, 0xff000000);
+ mFrameNoTransformPaint.setColor(0xff0000ff);
+ mFrameNoTransformPaint.setStyle(Paint.Style.STROKE);
+ mFrameNoTransformPaint.setStrokeWidth(0);
+ mFrameNoTransformPaint.setShadowLayer(density, density, density, 0xff000000);
}
public void setAssistStructure(AssistStructure as) {
mAssistStructure = as;
- mAssistStructure.dump();
mTextRects.clear();
final int N = as.getWindowNodeCount();
if (N > 0) {
for (int i=0; i<N; i++) {
AssistStructure.WindowNode windowNode = as.getWindowNodeAt(i);
- buildTextRects(windowNode.getRootViewNode(), windowNode.getLeft(),
+ mMatrixStack.clear();
+ Matrix matrix = new Matrix();
+ matrix.setTranslate(windowNode.getLeft(), windowNode.getTop());
+ mMatrixStack.add(matrix);
+ buildTextRects(windowNode.getRootViewNode(), 0, windowNode.getLeft(),
windowNode.getTop());
}
}
@@ -60,31 +92,62 @@ public class AssistVisualizer extends View {
invalidate();
}
+ public void logTree() {
+ if (mAssistStructure != null) {
+ mAssistStructure.dump();
+ }
+ }
+
+ public void logText() {
+ final int N = mTextRects.size();
+ for (int i=0; i<N; i++) {
+ TextEntry te = mTextRects.get(i);
+ Log.d(TAG, "View " + te.className + " " + te.bounds.toShortString()
+ + " in " + te.parentLeft + "," + te.parentTop
+ + " matrix=" + te.matrix.toShortString() + ": "
+ + te.text);
+ }
+ }
+
public void clearAssistData() {
mAssistStructure = null;
mTextRects.clear();
}
- void buildTextRects(AssistStructure.ViewNode root, int parentLeft, int parentTop) {
+ void buildTextRects(AssistStructure.ViewNode root, int matrixStackIndex,
+ int parentLeft, int parentTop) {
if (root.getVisibility() != View.VISIBLE) {
return;
}
- int left = parentLeft+root.getLeft();
- int top = parentTop+root.getTop();
+ Matrix parentMatrix = mMatrixStack.get(matrixStackIndex);
+ matrixStackIndex++;
+ Matrix matrix;
+ if (mMatrixStack.size() > matrixStackIndex) {
+ matrix = mMatrixStack.get(matrixStackIndex);
+ matrix.set(parentMatrix);
+ } else {
+ matrix = new Matrix(parentMatrix);
+ mMatrixStack.add(matrix);
+ }
+ matrix.preTranslate(root.getLeft(), root.getTop());
+ int left = parentLeft + root.getLeft();
+ int top = parentTop + root.getTop();
+ Matrix transform = root.getTransformation();
+ if (transform != null) {
+ matrix.preConcat(transform);
+ }
if (root.getText() != null || root.getContentDescription() != null) {
- Rect r = new Rect(left, top, left+root.getWidth(), top+root.getHeight());
- Log.d(TAG, "View " + root.getClassName() + " " + left + "," + top + " tr "
- + r.toShortString() + ": "
- + (root.getText() != null ? root.getText() : root.getContentDescription()));
- mTextRects.add(r);
+ TextEntry te = new TextEntry(root, parentLeft, parentTop, matrix);
+ mTextRects.add(te);
}
final int N = root.getChildCount();
if (N > 0) {
left -= root.getScrollX();
top -= root.getScrollY();
+ matrix.preTranslate(-root.getScrollX(), -root.getScrollY());
for (int i=0; i<N; i++) {
AssistStructure.ViewNode child = root.getChildAt(i);
- buildTextRects(child, left, top);
+ buildTextRects(child, matrixStackIndex, left, top);
}
}
}
@@ -96,9 +159,19 @@ public class AssistVisualizer extends View {
final int N = mTextRects.size();
Log.d(TAG, "Drawing text rects in " + this + ": found " + mTextRects.size());
for (int i=0; i<N; i++) {
- Rect r = mTextRects.get(i);
- canvas.drawRect(r.left-mTmpLocation[0], r.top-mTmpLocation[1],
- r.right-mTmpLocation[0], r.bottom-mTmpLocation[1], mFramePaint);
+ TextEntry te = mTextRects.get(i);
+ canvas.drawRect(te.bounds.left - mTmpLocation[0], te.bounds.top - mTmpLocation[1],
+ te.bounds.right - mTmpLocation[0], te.bounds.bottom - mTmpLocation[1],
+ mFrameNoTransformPaint);
+ }
+ for (int i=0; i<N; i++) {
+ TextEntry te = mTextRects.get(i);
+ canvas.save();
+ canvas.translate(-mTmpLocation[0], -mTmpLocation[1]);
+ canvas.concat(te.matrix);
+ canvas.drawRect(0, 0, te.bounds.right - te.bounds.left, te.bounds.bottom - te.bounds.top,
+ mFramePaint);
+ canvas.restore();
}
}
}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
index 578e356..8381aa1 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
@@ -80,7 +80,8 @@ public class MainInteractionService extends VoiceInteractionService {
Bundle args = new Bundle();
args.putParcelable("intent", new Intent(this, TestInteractionActivity.class));
args.putBundle("assist", intent.getExtras());
- startSession(args, VoiceInteractionSession.SHOW_WITH_ASSIST | VoiceInteractionSession.SHOW_WITH_SCREENSHOT);
+ showSession(args, VoiceInteractionSession.SHOW_WITH_ASSIST
+ | VoiceInteractionSession.SHOW_WITH_SCREENSHOT);
} else {
Log.w(TAG, "Not starting -- not current voice interaction service");
}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
index 90a781c..a6585ba 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
@@ -42,8 +42,11 @@ public class MainInteractionSession extends VoiceInteractionSession
View mTopContent;
View mBottomContent;
TextView mText;
+ Button mTreeButton;
+ Button mTextButton;
Button mStartButton;
ImageView mScreenshot;
+ ImageView mFullScreenshot;
Button mConfirmButton;
Button mCompleteButton;
Button mAbortButton;
@@ -57,7 +60,7 @@ public class MainInteractionSession extends VoiceInteractionSession
static final int STATE_COMMAND = 4;
static final int STATE_ABORT_VOICE = 5;
static final int STATE_COMPLETE_VOICE = 6;
- static final int STATE_DONE=7;
+ static final int STATE_DONE = 7;
int mState = STATE_IDLE;
VoiceInteractor.PickOptionRequest.Option[] mPendingOptions;
@@ -69,8 +72,8 @@ public class MainInteractionSession extends VoiceInteractionSession
}
@Override
- public void onCreate(Bundle args, int startFlags) {
- super.onCreate(args, startFlags);
+ public void onCreate() {
+ super.onCreate();
ActivityManager am = getContext().getSystemService(ActivityManager.class);
am.setWatchHeapLimit(40 * 1024 * 1024);
}
@@ -110,9 +113,15 @@ public class MainInteractionSession extends VoiceInteractionSession
mTopContent = mContentView.findViewById(R.id.top_content);
mBottomContent = mContentView.findViewById(R.id.bottom_content);
mText = (TextView)mContentView.findViewById(R.id.text);
+ mTreeButton = (Button)mContentView.findViewById(R.id.do_tree);
+ mTreeButton.setOnClickListener(this);
+ mTextButton = (Button)mContentView.findViewById(R.id.do_text);
+ mTextButton.setOnClickListener(this);
mStartButton = (Button)mContentView.findViewById(R.id.start);
mStartButton.setOnClickListener(this);
mScreenshot = (ImageView)mContentView.findViewById(R.id.screenshot);
+ mScreenshot.setOnClickListener(this);
+ mFullScreenshot = (ImageView)mContentView.findViewById(R.id.full_screenshot);
mConfirmButton = (Button)mContentView.findViewById(R.id.confirm);
mConfirmButton.setOnClickListener(this);
mCompleteButton = (Button)mContentView.findViewById(R.id.complete);
@@ -154,10 +163,12 @@ public class MainInteractionSession extends VoiceInteractionSession
if (screenshot != null) {
mScreenshot.setImageBitmap(screenshot);
mScreenshot.setAdjustViewBounds(true);
- mScreenshot.setMaxWidth(screenshot.getWidth()/3);
- mScreenshot.setMaxHeight(screenshot.getHeight()/3);
+ mScreenshot.setMaxWidth(screenshot.getWidth() / 3);
+ mScreenshot.setMaxHeight(screenshot.getHeight() / 3);
+ mFullScreenshot.setImageBitmap(screenshot);
} else {
mScreenshot.setImageDrawable(null);
+ mFullScreenshot.setImageDrawable(null);
}
}
@@ -183,16 +194,25 @@ public class MainInteractionSession extends VoiceInteractionSession
}
public void onClick(View v) {
- if (v == mStartButton) {
+ if (v == mTreeButton) {
+ if (mAssistVisualizer != null) {
+ mAssistVisualizer.logTree();
+ }
+ } else if (v == mTextButton) {
+ if (mAssistVisualizer != null) {
+ mAssistVisualizer.logText();
+ }
+ } else if (v == mStartButton) {
mState = STATE_LAUNCHING;
updateState();
startVoiceActivity(mStartIntent);
} else if (v == mConfirmButton) {
- if (mState == STATE_CONFIRM) {
- mPendingRequest.sendConfirmResult(true, null);
+ if (mPendingRequest instanceof ConfirmationRequest) {
+ ((ConfirmationRequest)mPendingRequest).sendConfirmationResult(true, null);
mPendingRequest = null;
mState = STATE_LAUNCHING;
- } else if (mState == STATE_PICK_OPTION) {
+ } else if (mPendingRequest instanceof PickOptionRequest) {
+ PickOptionRequest pick = (PickOptionRequest)mPendingRequest;
int numReturn = mPendingOptions.length/2;
if (numReturn <= 0) {
numReturn = 1;
@@ -204,24 +224,32 @@ public class MainInteractionSession extends VoiceInteractionSession
}
mPendingOptions = picked;
if (picked.length <= 1) {
- mPendingRequest.sendPickOptionResult(true, picked, null);
+ pick.sendPickOptionResult(picked, null);
mPendingRequest = null;
mState = STATE_LAUNCHING;
} else {
- mPendingRequest.sendPickOptionResult(false, picked, null);
+ pick.sendIntermediatePickOptionResult(picked, null);
updatePickText();
}
- } else if (mPendingRequest != null) {
- mPendingRequest.sendCommandResult(true, null);
+ } else if (mPendingRequest instanceof CommandRequest) {
+ Bundle result = new Bundle();
+ result.putString("key", "a result!");
+ ((CommandRequest)mPendingRequest).sendResult(result);
mPendingRequest = null;
mState = STATE_LAUNCHING;
}
- } else if (v == mAbortButton) {
- mPendingRequest.sendAbortVoiceResult(null);
+ } else if (v == mAbortButton && mPendingRequest instanceof AbortVoiceRequest) {
+ ((AbortVoiceRequest)mPendingRequest).sendAbortResult(null);
mPendingRequest = null;
- } else if (v== mCompleteButton) {
- mPendingRequest.sendCompleteVoiceResult(null);
+ } else if (v == mCompleteButton && mPendingRequest instanceof CompleteVoiceRequest) {
+ ((CompleteVoiceRequest)mPendingRequest).sendCompleteResult(null);
mPendingRequest = null;
+ } else if (v == mScreenshot) {
+ if (mFullScreenshot.getVisibility() != View.VISIBLE) {
+ mFullScreenshot.setVisibility(View.VISIBLE);
+ } else {
+ mFullScreenshot.setVisibility(View.INVISIBLE);
+ }
}
updateState();
}
@@ -236,29 +264,45 @@ public class MainInteractionSession extends VoiceInteractionSession
}
@Override
- public boolean[] onGetSupportedCommands(Caller caller, String[] commands) {
- return new boolean[commands.length];
+ public boolean[] onGetSupportedCommands(String[] commands) {
+ boolean[] res = new boolean[commands.length];
+ for (int i=0; i<commands.length; i++) {
+ if ("com.android.test.voiceinteraction.COMMAND".equals(commands[i])) {
+ res[i] = true;
+ }
+ }
+ return res;
}
+ void setPrompt(VoiceInteractor.Prompt prompt) {
+ if (prompt == null) {
+ mText.setText("(null)");
+ mPendingPrompt = "";
+ } else {
+ mText.setText(prompt.getVisualPrompt());
+ mPendingPrompt = prompt.getVisualPrompt();
+ }
+ }
+
@Override
- public void onConfirm(Caller caller, Request request, CharSequence prompt, Bundle extras) {
- Log.i(TAG, "onConfirm: prompt=" + prompt + " extras=" + extras);
- mText.setText(prompt);
+ public void onRequestConfirmation(ConfirmationRequest request) {
+ Log.i(TAG, "onConfirm: prompt=" + request.getVoicePrompt() + " extras="
+ + request.getExtras());
+ setPrompt(request.getVoicePrompt());
mConfirmButton.setText("Confirm");
mPendingRequest = request;
- mPendingPrompt = prompt;
mState = STATE_CONFIRM;
updateState();
}
@Override
- public void onPickOption(Caller caller, Request request, CharSequence prompt,
- VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) {
- Log.i(TAG, "onPickOption: prompt=" + prompt + " options=" + options + " extras=" + extras);
+ public void onRequestPickOption(PickOptionRequest request) {
+ Log.i(TAG, "onPickOption: prompt=" + request.getVoicePrompt() + " options="
+ + request.getOptions() + " extras=" + request.getExtras());
mConfirmButton.setText("Pick Option");
mPendingRequest = request;
- mPendingPrompt = prompt;
- mPendingOptions = options;
+ setPrompt(request.getVoicePrompt());
+ mPendingOptions = request.getOptions();
mState = STATE_PICK_OPTION;
updatePickText();
updateState();
@@ -278,27 +322,33 @@ public class MainInteractionSession extends VoiceInteractionSession
}
@Override
- public void onCompleteVoice(Caller caller, Request request, CharSequence message, Bundle extras) {
- Log.i(TAG, "onCompleteVoice: message=" + message + " extras=" + extras);
- mText.setText(message);
+ public void onRequestCompleteVoice(CompleteVoiceRequest request) {
+ Log.i(TAG, "onCompleteVoice: message=" + request.getVoicePrompt() + " extras="
+ + request.getExtras());
+ setPrompt(request.getVoicePrompt());
mPendingRequest = request;
mState = STATE_COMPLETE_VOICE;
updateState();
}
@Override
- public void onAbortVoice(Caller caller, Request request, CharSequence message, Bundle extras) {
- Log.i(TAG, "onAbortVoice: message=" + message + " extras=" + extras);
- mText.setText(message);
+ public void onRequestAbortVoice(AbortVoiceRequest request) {
+ Log.i(TAG, "onAbortVoice: message=" + request.getVoicePrompt() + " extras="
+ + request.getExtras());
+ setPrompt(request.getVoicePrompt());
mPendingRequest = request;
mState = STATE_ABORT_VOICE;
updateState();
}
@Override
- public void onCommand(Caller caller, Request request, String command, Bundle extras) {
- Log.i(TAG, "onCommand: command=" + command + " extras=" + extras);
- mText.setText("Command: " + command);
+ public void onRequestCommand(CommandRequest request) {
+ Bundle extras = request.getExtras();
+ if (extras != null) {
+ extras.getString("arg");
+ }
+ Log.i(TAG, "onCommand: command=" + request.getCommand() + " extras=" + extras);
+ mText.setText("Command: " + request.getCommand() + ", " + extras);
mConfirmButton.setText("Finish Command");
mPendingRequest = request;
mState = STATE_COMMAND;
@@ -306,8 +356,13 @@ public class MainInteractionSession extends VoiceInteractionSession
}
@Override
- public void onCancel(Request request) {
+ public void onCancelRequest(Request request) {
Log.i(TAG, "onCancel");
- request.sendCancelResult();
+ if (mPendingRequest == request) {
+ mPendingRequest = null;
+ mState = STATE_LAUNCHING;
+ updateState();
+ }
+ request.cancel();
}
}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
index 943c647..2487e1ca 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
@@ -33,6 +33,7 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis
static final String REQUEST_ABORT = "abort";
static final String REQUEST_COMPLETE = "complete";
+ static final String REQUEST_COMMAND = "command";
static final String REQUEST_PICK = "pick";
static final String REQUEST_CONFIRM = "confirm";
@@ -41,6 +42,7 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis
TextView mLog;
Button mAbortButton;
Button mCompleteButton;
+ Button mCommandButton;
Button mPickButton;
Button mJumpOutButton;
Button mCancelButton;
@@ -68,6 +70,8 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis
mAbortButton.setOnClickListener(this);
mCompleteButton = (Button)findViewById(R.id.complete);
mCompleteButton.setOnClickListener(this);
+ mCommandButton = (Button)findViewById(R.id.command);
+ mCommandButton.setOnClickListener(this);
mPickButton = (Button)findViewById(R.id.pick);
mPickButton.setOnClickListener(this);
mJumpOutButton = (Button)findViewById(R.id.jump);
@@ -117,6 +121,9 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis
} else if (v == mCompleteButton) {
VoiceInteractor.CompleteVoiceRequest req = new TestCompleteVoice();
mInteractor.submitRequest(req, REQUEST_COMPLETE);
+ } else if (v == mCommandButton) {
+ VoiceInteractor.CommandRequest req = new TestCommand("Some arg");
+ mInteractor.submitRequest(req, REQUEST_COMMAND);
} else if (v == mPickButton) {
VoiceInteractor.PickOptionRequest.Option[] options =
new VoiceInteractor.PickOptionRequest.Option[5];
@@ -176,6 +183,37 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis
}
}
+ static class TestCommand extends VoiceInteractor.CommandRequest {
+ public TestCommand(String arg) {
+ super("com.android.test.voiceinteraction.COMMAND", makeBundle(arg));
+ }
+ @Override public void onCancel() {
+ Log.i(TAG, "Canceled!");
+ ((TestInteractionActivity)getActivity()).mLog.append("Canceled command\n");
+ }
+ @Override
+ public void onCommandResult(boolean finished, Bundle result) {
+ Log.i(TAG, "Command result: finished=" + finished + " result=" + result);
+ StringBuilder sb = new StringBuilder();
+ if (finished) {
+ sb.append("Command final result: ");
+ } else {
+ sb.append("Command intermediate result: ");
+ }
+ if (result != null) {
+ result.getString("key");
+ }
+ sb.append(result);
+ sb.append("\n");
+ ((TestInteractionActivity)getActivity()).mLog.append(sb.toString());
+ }
+ static Bundle makeBundle(String arg) {
+ Bundle b = new Bundle();
+ b.putString("key", arg);
+ return b;
+ }
+ }
+
static class TestPickOption extends VoiceInteractor.PickOptionRequest {
public TestPickOption(Option[] options) {
super(new VoiceInteractor.Prompt("Need to pick something"), options, null);
@@ -200,10 +238,8 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis
}
sb.append(selections[i].getLabel());
}
+ sb.append("\n");
((TestInteractionActivity)getActivity()).mLog.append(sb.toString());
- if (finished) {
- getActivity().finish();
- }
}
}
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 422b2aa..582ac33 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -742,7 +742,7 @@ public final class BridgeContext extends Context {
if (item != null) {
// item is a reference to a style entry. Search for it.
item = mRenderResources.findResValue(item.getValue(), item.isFramework());
-
+ item = mRenderResources.resolveResValue(item);
if (item instanceof StyleResourceValue) {
defStyleValues = (StyleResourceValue) item;
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
index c92df6d..bea1f86 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
@@ -47,7 +47,7 @@ public final class BridgeWindowSession implements IWindowSession {
@Override
public int addToDisplay(IWindow arg0, int seq, LayoutParams arg1, int arg2, int displayId,
- Rect arg3, Rect arg4, InputChannel outInputchannel)
+ Rect arg3, Rect arg4, Rect arg5, InputChannel outInputchannel)
throws RemoteException {
// pass for now.
return 0;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
index 8b8cc38..958b7aa 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
@@ -151,7 +151,7 @@ public class AppCompatActionBar extends BridgeActionBar {
@Override
public void createMenuPopup() {
- // it's hard to addd menus to appcompat's actionbar, since it'll use a lot of reflection.
+ // it's hard to add menus to appcompat's actionbar, since it'll use a lot of reflection.
// so we skip it for now.
}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
index f6c2626..dae5509 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
@@ -94,14 +94,8 @@ public class AsmGenerator {
ListIterator<Class<?>> iter = injectedClasses.listIterator();
while (iter.hasNext()) {
Class<?> clazz = iter.next();
- try {
- int i = 1;
- while(i < 100) {
- iter.add(Class.forName(clazz.getName() + "$" + i));
- i++;
- }
- } catch (ClassNotFoundException ignored) {
- // Expected.
+ for (Class<?> aClass : clazz.getDeclaredClasses()) {
+ iter.add(aClass);
}
}
mInjectClasses = injectedClasses.toArray(new Class<?>[0]);
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index fc6a3de..cc1e976 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -216,11 +216,15 @@ public class ScanResult implements Parcelable {
*/
public int distanceSdCm;
+ /** {@hide} */
public static final long FLAG_PASSPOINT_NETWORK = 0x0000000000000001;
+
+ /** {@hide} */
public static final long FLAG_80211mc_RESPONDER = 0x0000000000000002;
/**
* Defines flags; such as {@link #FLAG_PASSPOINT_NETWORK}.
+ * {@hide}
*/
public long flags;
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 5d834f6..dc329e2 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -352,7 +352,7 @@ public class WifiConfiguration implements Parcelable {
* Roaming Consortium Id list for passpoint credential; identifies a set of networks where
* passpoint credential will be considered valid
*/
- public Long[] roamingConsortiumIds;
+ public long[] roamingConsortiumIds;
/**
* @hide
@@ -907,7 +907,7 @@ public class WifiConfiguration implements Parcelable {
SSID = null;
BSSID = null;
FQDN = null;
- roamingConsortiumIds = new Long[0];
+ roamingConsortiumIds = new long[0];
priority = 0;
hiddenSSID = false;
disableReason = DISABLED_UNKNOWN_REASON;
@@ -1014,10 +1014,10 @@ public class WifiConfiguration implements Parcelable {
sbuf.append(this.numNoInternetAccessReports).append("\n");
}
if (this.updateTime != null) {
- sbuf.append("creation=").append(this.updateTime).append("\n");
+ sbuf.append("update ").append(this.updateTime).append("\n");
}
if (this.creationTime != null) {
- sbuf.append("update=").append(this.creationTime).append("\n");
+ sbuf.append("creation").append(this.creationTime).append("\n");
}
if (this.didSelfAdd) sbuf.append(" didSelfAdd");
if (this.selfAdded) sbuf.append(" selfAdded");
@@ -1544,7 +1544,7 @@ public class WifiConfiguration implements Parcelable {
dest.writeString(FQDN);
dest.writeString(providerFriendlyName);
dest.writeInt(roamingConsortiumIds.length);
- for (Long roamingConsortiumId : roamingConsortiumIds) {
+ for (long roamingConsortiumId : roamingConsortiumIds) {
dest.writeLong(roamingConsortiumId);
}
dest.writeString(preSharedKey);
@@ -1619,7 +1619,7 @@ public class WifiConfiguration implements Parcelable {
config.FQDN = in.readString();
config.providerFriendlyName = in.readString();
int numRoamingConsortiumIds = in.readInt();
- config.roamingConsortiumIds = new Long[numRoamingConsortiumIds];
+ config.roamingConsortiumIds = new long[numRoamingConsortiumIds];
for (int i = 0; i < numRoamingConsortiumIds; i++) {
config.roamingConsortiumIds[i] = in.readLong();
}
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index 2ba38e1..e25b38c 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -101,6 +101,8 @@ public class WifiInfo implements Parcelable {
private InetAddress mIpAddress;
private String mMacAddress = DEFAULT_MAC_ADDRESS;
+ private boolean mEphemeral;
+
/**
* @hide
*/
@@ -253,6 +255,7 @@ public class WifiInfo implements Parcelable {
setLinkSpeed(-1);
setFrequency(-1);
setMeteredHint(false);
+ setEphemeral(false);
txBad = 0;
txSuccess = 0;
rxSuccess = 0;
@@ -283,6 +286,7 @@ public class WifiInfo implements Parcelable {
mIpAddress = source.mIpAddress;
mMacAddress = source.mMacAddress;
mMeteredHint = source.mMeteredHint;
+ mEphemeral = source.mEphemeral;
txBad = source.txBad;
txRetries = source.txRetries;
txSuccess = source.txSuccess;
@@ -430,6 +434,16 @@ public class WifiInfo implements Parcelable {
return mMeteredHint;
}
+ /** {@hide} */
+ public void setEphemeral(boolean ephemeral) {
+ mEphemeral = ephemeral;
+ }
+
+ /** {@hide} */
+ public boolean isEphemeral() {
+ return mEphemeral;
+ }
+
/** @hide */
public void setNetworkId(int id) {
mNetworkId = id;
@@ -567,6 +581,7 @@ public class WifiInfo implements Parcelable {
dest.writeString(mBSSID);
dest.writeString(mMacAddress);
dest.writeInt(mMeteredHint ? 1 : 0);
+ dest.writeInt(mEphemeral ? 1 : 0);
dest.writeInt(score);
dest.writeDouble(txSuccessRate);
dest.writeDouble(txRetriesRate);
@@ -597,6 +612,7 @@ public class WifiInfo implements Parcelable {
info.mBSSID = in.readString();
info.mMacAddress = in.readString();
info.mMeteredHint = in.readInt() != 0;
+ info.mEphemeral = in.readInt() != 0;
info.score = in.readInt();
info.txSuccessRate = in.readDouble();
info.txRetriesRate = in.readDouble();