API 수준: 17
Android 4.2(JELLY_BEAN_MR1
)는 사용자와 앱 개발자를 위한 새로운 기능을 제공하는 Jelly Bean 출시의 업데이트입니다. 이 문서에서는 Google Cloud Platform을 구성하는
개발자에게 유용한 새 API를 제공합니다.
앱 개발자라면 다음에서 Android 4.2 시스템 이미지와 SDK 플랫폼을 다운로드해야 합니다. SDK Manager에 액세스할 수 있어야 합니다. 앱을 테스트할 Android 4.2를 실행하는 기기가 없는 경우, Android 4.2 시스템 이미지를 사용하여 Android 에뮬레이터에서 앱을 테스트하세요. 그런 다음 Android 4.2 플랫폼을 대상으로 앱을 빌드하여 최신 API를 사용하세요.
Android 4.2를 실행하는 기기에 대해 앱을 보다 적절하게 최적화하려면 targetSdkVersion
를 "17"
로 설정하고 Android 4.2 시스템 이미지에 설치하여 테스트한 다음 이 변경사항과 함께 업데이트를 게시합니다.
나
는 Android 4.2에서 API를 사용하는 동시에
실행하기 전에 시스템 API 수준을 확인하는 코드에 대한 조건
minSdkVersion
에서 지원되지 않는 API
이전 버전과의 호환성을 유지하는 방법에 관한 자세한 내용은 이전 버전과 호환되는 UI 만들기를 참고하세요.
API 수준의 작동 방식에 대한 자세한 내용은 API란 무엇인가요? 레벨?
중요한 동작 변경 사항
이전에 Android용 앱을 게시한 적이 있는 경우 다음 사항에 유의하세요. 앱의 동작에 영향을 미칠 수 있는 변경사항:
- 콘텐츠 제공자는 더 이상 기본적으로 내보내지 않습니다. 즉,
android:exported
속성의 기본값은 이제“false"
입니다. 다른 앱이 콘텐츠 제공자에 액세스할 수 있게 되면 이제android:exported="true"
를 명시적으로 설정해야 합니다.이 변경사항은
android:targetSdkVersion
또는android:minSdkVersion
를 17 이상으로 설정한 경우에만 적용됩니다. 그 외의 경우 Android 4.2 이상에서 실행하더라도 기본값은 여전히“true"
입니다. - 이전 버전의 Android에 비해 사용자 위치 결과의 정확도가 떨어질 수 있습니다.
앱에서
ACCESS_COARSE_LOCATION
권한을 요청하지만ACCESS_FINE_LOCATION
권한을 요청하지 않습니다.앱에서 세밀한 위치가 아닌 대략적인 위치 정보 액세스 권한을 요청할 때 사용자의 개인 정보 보호 기대치를 충족하기 위해 시스템은 블록보다 더 정확한 사용자 위치 추정치를 제공하지 않습니다.
- 이제
Settings.System
에서 정의한 일부 기기 설정이 변경되었습니다. 읽기 전용입니다. 앱이Settings.System
에 정의된 설정 변경사항을Settings.Global
로 이동한 후 이를 쓰려고 시도하면 Android 4.2 이상에서 실행할 때 쓰기 작업이 자동으로 실패합니다.android:targetSdkVersion
및android:minSdkVersion
의 값이 17보다 낮더라도 앱은 Android 4.2 이상에서 실행될 때Settings.Global
로 이동한 설정을 수정할 수 없습니다. - 앱에서
WebView
를 사용하는 경우 Android 4.2에서는 JavaScript를 Android 코드에 더 안전하게 바인딩할 수 있도록 보안 레이어를 추가합니다. 만약targetSdkVersion
드림 17 이상으로 업데이트했다면 이제 런타임 시 실행할 모든 메서드에@JavascriptInterface
주석을 사용할 수 있습니다 (메서드도 공개 상태여야 함). 고객 ID를 제공하지 않으면WebView
의 웹페이지에서 메서드에 액세스할 수 없습니다. (Android 4.2 이상에서 실행 시)targetSdkVersion
를 16 이하로 설정하면 주석이 필요하지 않지만, 보안 강화를 위해 대상 버전을 업데이트하고 주석을 추가하는 것이 좋습니다.JavaScript 코드를 Android 코드에 결합에 대해 자세히 알아보세요.
Daydream
Daydream은 Android 기기의 새로운 대화형 화면 보호기 모드입니다. 자동으로 활성화됩니다. 기기가 도크에 삽입되거나 전원 콘센트에 연결되어 있는 동안 유휴 상태일 때 충전기를 사용합니다. Daydream은 한 번에 하나의 드림을 표시하며, 이는 터치 시 닫히는 순수한 시각적 수동 디스플레이일 수도 있고, 모든 입력 이벤트에 반응하는 양방향 디스플레이일 수도 있습니다. 드림은 앱 프로세스에서 실행되며 뷰, 레이아웃, 애니메이션을 비롯한 Android UI 도구 키트에 대한 전체 액세스 권한이 있으므로 라이브 배경화면이나 앱 위젯보다 유연하고 강력합니다.
DreamService
의 서브클래스를 구현하여 Daydream용 드림을 만들 수 있습니다. DreamService
API는 Activity
API와 유사하게 설계되었습니다. 앱의 UI를 지정하려면
꿈을 꾸고 나면 언제든지 레이아웃 리소스 ID 또는 View
를 setContentView()
에 전달합니다.
창(예: onAttachedToWindow()
에서)
있습니다.
DreamService
클래스는 다른 중요한 수명 주기 콜백을 제공합니다.
기본 Service
API 외에 onDreamingStarted()
, onDreamingStopped()
, onDetachedFromWindow()
등의 메서드도 사용할 수 있습니다.
앱에서 DreamService
를 시작할 수는 없으며 시스템에서 자동으로 실행됩니다.
드림이 대화형인 경우 드림에서 활동을 시작하여 사용자를 앱의 전체 UI로 전송하여 세부정보를 확인하거나 제어할 수 있습니다. finish()
를 사용하여 꿈을 종료하면 사용자가
확인할 수 있습니다.
시스템에서 Daydream을 사용할 수 있도록 하려면 <service>
요소로 DreamService
를 선언합니다.
매니페스트 파일에 포함됩니다. 그런 다음 "android.service.dreams.DreamService"
작업이 있는 인텐트 필터를 포함해야 합니다. 예를 들면 다음과 같습니다.
<service android:name=".MyDream" android:exported="true" android:icon="@drawable/dream_icon" android:label="@string/dream_label" > <intent-filter> <action android:name="android.service.dreams.DreamService" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </service>
DreamService
에는 알아두어야 할 몇 가지 유용한 메서드가 있습니다.
setInteractive(boolean)
에서 제어 가능 꿈은 입력 이벤트를 수신하거나 사용자 입력 즉시 종료됩니다. 드림이 양방향인 경우 사용자는 뒤로 또는 홈 버튼을 사용하여 드림을 종료하거나 개발자가finish()
를 호출하여 드림을 중지할 수 있습니다.- 완전한 몰입형 디스플레이를 원한다면
setFullscreen()
를 호출하여 상태 표시줄을 숨길 수 있습니다. - Daydream이 시작되기 전에 디스플레이가 어두워져 사용자에게 유휴 시간 제한이 다가오고 있음을 알립니다.
setScreenBright(true)
를 호출하면 대신 디스플레이를 평소 밝기로 설정할 수 있습니다.
자세한 내용은 DreamService
문서를 참고하세요.
보조 디스플레이
이제 Android를 통해 앱이 유선 연결 또는 Wi-Fi를 통해 사용자 기기에 연결된 추가 화면에 고유한 콘텐츠를 표시할 수 있습니다.
보조 디스플레이를 위한 고유한 콘텐츠를 생성하려면 Presentation
를 확장합니다.
클래스를 열고 onCreate()
콜백을 구현합니다. 이내
onCreate()
: 보조 디스플레이의 UI 지정
이를 위해 setContentView()
를 호출합니다.
Dialog
클래스의 확장인 Presentation
클래스는 앱이 보조 디스플레이에 고유한 UI를 표시할 수 있는 영역을 제공합니다.
Presentation
를 표시할 수 있는 보조 디스플레이를 감지하려면 다음 단계를 따르세요.
DisplayManager
또는 MediaRouter
사용
API에 액세스할 수 있습니다 DisplayManager
API를 사용하면
여러 개의 디스플레이에 빠르게 액세스하는 대신 일반적으로 MediaRouter
를 사용하여 시스템의 기본 디스플레이에 빠르게
여러 가지 방법이 있습니다.
프레젠테이션의 기본 디스플레이를 가져오려면 MediaRouter.getSelectedRoute()
를 호출하고 ROUTE_TYPE_LIVE_VIDEO
를 전달합니다. 이렇게 하면 시스템의 현재 선택된 경로를 설명하는 MediaRouter.RouteInfo
객체가 반환됩니다.
동영상 프레젠테이션에 사용할 수 있습니다. MediaRouter.RouteInfo
가 null이 아닌 경우 getPresentationDisplay()
를 호출하여 연결된 디스플레이를 나타내는 Display
를 가져옵니다.
그런 다음 Display
객체를 전달하여 프레젠테이션을 표시할 수 있습니다.
Presentation
클래스의 생성자에 전달됩니다. 이제 프레젠테이션이
보조 디스플레이에 표시됩니다.
런타임에 새 디스플레이가 연결되었는지 감지하려면 MediaRouter.SimpleCallback
인스턴스를 만들고 새 프레젠테이션 디스플레이가 연결될 때 시스템에서 호출하는 onRoutePresentationDisplayChanged()
콜백 메서드를 구현합니다. 그런 다음 ROUTE_TYPE_LIVE_VIDEO
경로 유형과 함께 MediaRouter.SimpleCallback
를 MediaRouter.addCallback()
에 전달하여 등록합니다. onRoutePresentationDisplayChanged()
호출을 수신하면 위에서 언급한 대로 MediaRouter.getSelectedRoute()
를 호출하면 됩니다.
보조 화면에 맞게 Presentation
의 UI를 더욱 최적화하려면 애플리케이션 또는 활동에 적용한 <style>
에서 android:presentationTheme
속성을 지정하여 다른 테마를 적용할 수 있습니다.
사용자의 기기에 연결된 화면은 화면 크기가 더 크고 화면 밀도가 다를 수 있습니다. 화면 특성이 다를 수 있으므로 이러한 대형 디스플레이에 맞게 최적화된 리소스를 제공해야 합니다. Presentation
에서 추가 리소스를 요청해야 하는 경우 getContext()
.getResources()
를 호출하여 디스플레이에 해당하는 Resources
객체를 가져옵니다. 이렇게 하면 보조 디스플레이의 화면 크기 및 밀도에 가장 적합한 앱의 적절한 리소스가 제공됩니다.
자세한 내용과 코드 샘플은 Presentation
를 참고하세요.
클래스 문서를 참조하세요.
잠금 화면 위젯
이제 Android에서 사용자가 잠금 화면에 앱 위젯을 추가할 수 있습니다. 앱 위젯을 잠금 화면에서 사용할 수 있도록 하려면 AppWidgetProviderInfo
를 지정하는 XML 파일에 android:widgetCategory
속성을 추가합니다. 이 속성은 home_screen
및 keyguard
의 두 가지 값을 지원합니다. 기본적으로 이 속성은 home_screen
로 설정되므로
앱 위젯을 홈 화면에 추가할 수도 있습니다. 앱 위젯을 잠금 화면에서도 사용할 수 있도록 하려면 keyguard
값을 추가합니다.
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" ... android:widgetCategory="keyguard|home_screen"> </appwidget-provider>
또한 android:initialKeyguardLayout
속성을 사용하여 잠금 화면에서 앱 위젯의 초기 레이아웃을 지정해야 합니다. 이는 다음을 제공한다는 점에서 android:initialLayout
와 동일한 방식으로 작동합니다.
이 레이아웃은 앱 위젯이 초기화되고
있습니다.
적절하게 잠금 화면에서 앱 위젯의 크기를 조정하는 방법은 앱 위젯 가이드를 참조하세요.
여러 사용자
Android는 이제 태블릿과 같은 공유 가능한 기기에서 여러 사용자 공간을 허용합니다. 기기의 각 사용자는 자체 계정, 앱, 시스템 설정, 파일, 기타 사용자 관련 데이터를 보유합니다.
앱 개발자가 앱 작동을 위해 별도로 취해야 할 조치는 없습니다. 여러 사용자가 하나의 기기에서 원활하게 소통할 수 있습니다. 페이지에 존재할 수 있는 사용자가 몇 명이든 앱이 특정 사용자에 대해 저장하는 데이터는 앱이 저장하는 데이터와 별도로 보관됩니다. 공유할 수 있습니다. 시스템은 어떤 사용자 데이터가 어떤 사용자 프로세스에 속하는지 앱이 실행 중이고 해당 사용자의 데이터에 대한 액세스만 앱에 제공하고 다른 사용자의 데이터에 액세스할 수 없습니다.
멀티 사용자 환경에서 데이터 저장
앱이 사용자 환경설정을 저장하거나, 데이터베이스를 만들거나, 사용자의 내부 저장소 또는 외부 저장소 공간에 파일을 쓸 때마다 해당 데이터는 해당 사용자로 실행되는 동안에만 액세스할 수 있습니다.
앱이 멀티 사용자 환경에서 제대로 동작하는지 확인하려면 내부 앱 디렉터리 또는 외부 저장소 위치에 저장합니다. 그 대신 항상 적절한 API를 제공합니다.
- 내부 저장소에 액세스하려면
getFilesDir()
,getCacheDir()
또는openFileOutput()
를 사용하세요. - 외부 저장소에 액세스하려면
getExternalFilesDir()
또는getExternalStoragePublicDirectory()
를 사용하세요.
어떤 API를 사용하여 특정 사용자의 데이터를 저장하든 데이터는 다른 사용자로 실행되는 동안 액세스 할 수 있습니다. 앱의 관점에서 보면 각 사용자는 완전히 별개의 기기에서 실행됩니다.
멀티 사용자 환경에서 사용자 식별
앱에서 애널리틱스를 수집하거나 다른 계정을 만드는 등 순 사용자를 식별하려는 경우
연결을 식별하려는 경우
고유한 설치를 제공합니다. 앱이 처음 시작될 때 새 UUID
를 만들면 단일 기기에 앱을 설치한 사용자 수와 관계없이 각 사용자를 추적할 수 있는 고유 ID를 얻을 수 있습니다. 또는 API에서 가져온 로컬 토큰을
서버에 연결하거나 Google 클라우드 메시징에서 제공하는 등록 ID를 사용하세요.
앱에서 하드웨어 기기 식별자 (예: Wi-Fi MAC 주소) 중 하나를 요청하는 경우
주소 또는 SERIAL
번호)는 각각에 대해 동일한 값을 제공합니다.
사용자에게 서비스를 요청할 수 있습니다. 앱 설치 식별 블로그 게시물에서 설명한 대로 이러한 식별자가 도입하는 다른 문제도 있습니다.
새로운 글로벌 설정
Settings.Global
를 추가하여 여러 사용자를 지원하도록 시스템 설정이 업데이트되었습니다. 이 설정 모음은 읽기 전용이지만 모든 영역에 전역적으로 적용된다는 점에서 Settings.Secure
설정과 유사합니다.
기기의 모든 사용자 공간을 대상으로 합니다.
기존의 여러 설정이 Settings.System
또는 Settings.Secure
에서 이 위치로 이전되었습니다. 앱이 현재 Settings.System
에 정의된 설정(예: AIRPLANE_MODE_ON
)을 변경하는 경우, 이러한 설정이 Settings.Global
로 이동된 경우 Android 4.2 이상을 실행하는 기기에서 더 이상 작동하지 않을 것으로 예상해야 합니다. 다음 설정을 계속 읽을 수 있습니다.
Settings.Global
, 설정이 더 이상 안전하지 않다고 간주됨
변경하려고 하면 자동으로 실패하고 시스템은
시스템 로그를 확인하는 데 사용됩니다.
RTL 레이아웃 지원
이제 Android에서는 아랍어 및 히브리어와 같이 오른쪽에서 왼쪽(RTL) UI 및 읽기 방향을 사용하는 언어를 지원하도록 레이아웃 방향을 원활하게 변환하는 사용자 인터페이스를 빌드할 수 있는 여러 API를 제공합니다.
앱에서 RTL 레이아웃 지원을 시작하려면 매니페스트 파일에서 android:supportsRtl
속성을 <application>
요소로 설정하세요.
그런 다음 “true"
로 설정합니다. 이를 사용 설정하면 시스템에서 다양한 RTL API를 사용 설정하여
앱을 RTL 레이아웃으로 표시해야 합니다. 예를 들어 작업 표시줄에는 아이콘과 제목이 오른쪽에, 작업 버튼이 왼쪽에 표시되며 프레임워크에서 제공하는 View
클래스로 만든 모든 레이아웃도 반전됩니다.
RTL 레이아웃으로 표시될 때 앱의 모양을 더 최적화해야 하는 경우 다음과 같은 두 가지 기본 최적화 수준이 있습니다.
- 왼쪽 및 오른쪽 방향 레이아웃 속성을 시작 및 끝 방향 레이아웃으로 변환
속성
예를 들어
android:layout_marginLeft
대신android:layout_marginStart
를 사용하고android:layout_marginRight
대신android:layout_marginEnd
를 사용합니다.RelativeLayout
클래스는 왼쪽/오른쪽 위치를 대체하는 상응하는 레이아웃 속성도 제공합니다(예:android:layout_alignParentStart
:android:layout_alignParentLeft
대체,android:layout_toLeftOf
대신android:layout_toStartOf
). - 또는 RTL 레이아웃에 대한 완전한 최적화를 제공하려면
ldrtl
리소스 한정자를 사용하여 완전히 별개의 레이아웃 파일을 제공할 수 있습니다(ldrtl
는 layout-direction-right-to-left를 나타냄). 예를 들어 기본 레이아웃 파일을res/layout/
및res/layout-ldrtl/
의 RTL 최적화 레이아웃ldrtl
한정자는 드로어블 리소스에 유용하므로 개발자는 다음과 같은 특성을 가질 수 있습니다. 읽는 방향에 해당하는 방향이 지정된 그래픽을 사용합니다.
RTL 레이아웃을 지원하기 위해 프레임워크 전반에 다음과 같은 다양한 기타 API를 사용할 수 있습니다.
맞춤의 적절한 동작을 구현할 수 있도록 View
클래스
뷰와 Configuration
에서 현재 레이아웃 방향을 쿼리합니다.
참고: SQlite를 사용 중이고 '숫자만' 포함된 테이블이나 열 이름이 있는 경우 주의하세요. String.format(String, Object...)
를 사용하면 기기가 아랍어 언어로 설정된 경우 숫자가 아랍어 등가 값으로 변환되는 오류가 발생할 수 있습니다.
String.format(Locale,String,Object...)
를 사용하여 숫자가
ASCII로 보존됩니다. 또한String.format("%d", int)
String.valueOf(int)
-
숫자 서식 지정
중첩된 프래그먼트
이제 프래그먼트 내에 프래그먼트를 삽입할 수 있습니다. 이는 다양한 상황에서
동적이고 재사용 가능한 UI 구성요소를 그 자체인 UI 구성요소에 배치하려는 경우
동적이고 재사용이 가능합니다 예를 들어 ViewPager
를 사용하여
좌우로 스와이프하고 화면 공간의 대부분을 차지하는 프래그먼트를 만드는 경우,
이제 각 프래그먼트 페이지에 프래그먼트를 삽입합니다.
프래그먼트를 중첩하려면 프래그먼트를 추가하려는 Fragment
에서 getChildFragmentManager()
를 호출하면 됩니다. 이렇게 하면 일반적으로 최상위 활동에서 프래그먼트 트랜잭션을 만들 때와 같이 사용할 수 있는 FragmentManager
가 반환됩니다. 예를 들어, 다음은 내부에서 프래그먼트를 추가하는 몇 가지 코드입니다.
기존 Fragment
클래스:
Kotlin
val videoFragment = VideoPlayerFragment() childFragmentManager.beginTransaction().apply { add(R.id.video_fragment, videoFragment) commit() }
자바
Fragment videoFragment = new VideoPlayerFragment(); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); transaction.add(R.id.video_fragment, videoFragment).commit();
중첩된 프래그먼트 내에서 getParentFragment()
를 호출하여 상위 프래그먼트 참조를 가져올 수 있습니다.
이제 Android 지원 라이브러리에서 중첩된 프래그먼트도 지원하므로 Android 1.6 이상에서 중첩된 프래그먼트 디자인을 구현할 수 있습니다.
참고: 이 경우 레이아웃을 프래그먼트로 확장할 수 없습니다.
<fragment>
포함 중첩된 프래그먼트는 프래그먼트에 동적으로 추가된 경우에만 지원됩니다.
Renderscript
RenderScript 계산 기능이 다음 기능을 통해 향상되었습니다.
- 스크립트 내장 기능
Renderscript의 내장 스크립트 내장 함수를 사용하여 일반적인 작업을 수행할 수 있습니다
Blends
Blur
Color matrix
3x3 convolve
5x5 convolve
Per-channel lookup table
Converting an Android YUV buffer to RGB
스크립트 내장 기능을 사용하려면 각 내장 기능의 정적
create()
메서드를 호출합니다. 스크립트의 인스턴스를 생성합니다. 그런 다음 사용 가능한set()
를 호출합니다. 메서드를 사용하여 필요한 입력 및 옵션을 설정할 수 있습니다. 마지막으로forEach()
를 호출합니다. 메서드를 사용하여 스크립트를 실행합니다.- 스크립트 그룹
-
ScriptGroup
를 사용하면 관련 Renderscript를 연결할 수 있습니다. 스크립트를 작성하고 한 번의 호출로 실행할 수 있습니다.ScriptGroup.Builder
를 사용하여addKernel()
를 호출하여 모든 스크립트를 그룹에 추가합니다. 작업한 후에는 모든 스크립트를 추가하고addConnection()
를 호출하여 스크립트를 작성할 수 있습니다. 연결 추가가 완료되면create()
를 호출하여 스크립트 그룹을 만듭니다. 스크립트 그룹을 실행하기 전에 입력Allocation
및setInput(Script.KernelID, Allocation)
메서드로 실행할 초기 스크립트를 지정하고 결과가 쓰여질 출력Allocation
및setOutput()
로 실행할 최종 스크립트를 제공합니다. 마지막으로execute()
를 호출하여 스크립트 그룹을 실행합니다. - 필터링 스크립트
-
Filterscript는 결과 코드가 더 다양한 프로세서(CPU, GPU, DSP)에서 실행될 수 있도록 기존 Renderscript API에 제약 조건을 정의합니다. Filterscript 파일을 만들려면
.fs
을(를) 만드세요. 파일을.rs
파일 대신 사용하고#pragma rs_fp_relaxed
Renderscript 런타임에 스크립트에 엄격한 IEEE 754-2008 부동 소수점 정밀도가 필요하지 않음을 알립니다. 이러한 정밀도는 변이의 경우 플러시-제로와 0 방향의 반올림을 허용합니다. 또한 Filterscript는 스크립트에서 32비트 기본 제공 유형을 사용해서는 안 되며,__attribute__((kernel))
속성입니다. Filterscript가 포인터를 지원하지 않기 때문입니다.root()
함수의 기본 서명이 정의합니다.
참고: Filterscript 지원은 플랫폼에 있지만 개발자 지원은 SDK 도구 출시 21.0.1에서 제공됩니다.
Android 4.2의 모든 API 변경사항에 대한 자세한 내용은 API 차이점 보고서를 참고하세요.