Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

Android 4.4 API

API 레벨: 19

Android 4.4(KITKAT)는 사용자와 앱 개발자에게 새로운 기능을 제공하는 Android 플랫폼을 위한 새 릴리스입니다. 이 문서에서는 가장 주목할 새로운 API를 소개합니다.

앱 개발자인 경우에는 가능한 빨리 SDK Manager에서 Android 4.4 시스템 이미지와 SDK 플랫폼을 다운로드하세요. 앱을 테스트할 Android 4.4를 실행하는 기기가 없는 경우, Android 4.4 시스템 이미지를 사용하여 Android 에뮬레이터에서 앱을 테스트하세요. 그런 다음 최신 API를 사용할 수 있도록 Android 4.4 플랫폼을 대상으로 앱을 빌드하세요.

대상 API 레벨 업데이트

Android 4.4를 실행하는 기기에 대해 앱을 보다 적절하게 최적화하려면, targetSdkVersion"19"로 설정하고 Android 4.4 시스템 이미지에 설치하여 테스트한 다음 이 변경 사항과 함께 업데이트를 게시합니다.

minSdkVersion이 지원하지 않는 API를 실행하기 전에 시스템 API 레벨을 확인하는 코드에 조건을 추가하여 이전 버전을 지원하면서도 Android 4.4에서 API를 사용할 수 있습니다. 이전 버전과의 호환성을 유지하는 방법에 관한 자세한 정보를 보려면 다양한 플랫폼 버전 지원을 참조하세요.

API 레벨이 작동하는 방식에 관한 자세한 정보는 API 레벨이란?을 참조하세요.

중요한 동작 변경 사항

이전에 Android용 앱을 게시한 적이 있는 경우, Android 4.4의 변경으로 인해 앱이 영향을 받을 수 있다는 점을 유의하세요.

앱이 외부 저장소에서 읽는 경우...

앱에 READ_EXTERNAL_STORAGE 권한이 없으면, 앱을 Android 4.4에서 실행하는 동안 외부 저장소의 공유 파일을 읽을 수 없습니다. 다시 말해, 디렉터리 내에서 getExternalStoragePublicDirectory()를 통해 반환된 파일은 권한이 없으면 더 이상 액세스할 수 없습니다. 하지만 getExternalFilesDir()을 통해 제공된 앱 고유의 디렉터리에 대한 액세스만 필요한 경우에는 READ_EXTERNAL_STORAGE 권한이 필요하지 않습니다.

앱이 WebView를 사용하는 경우...

특히 앱의 targetSdkVersion을 "19" 이상으로 업데이트할 때, Android 4.4에서 앱을 실행하면 다르게 작동할 수 있습니다.

WebView 클래스 및 관련 API의 기본 코드가 Chromium 소스 코드의 최신 스냅샷에 기반하도록 업데이트되었습니다. 따라서 성능을 다양하게 개선하고 새 HTML5 기능을 지원하며 WebView 콘텐츠의 원격 디버깅을 지원할 수 있습니다. 이러한 업그레이드의 범위로 인해 앱이 WebView를 사용할 때 경우에 따라서 일부 동작이 영향을 받을 수 있습니다. 알려진 동작 변경은 문서화되어 있으며 대부분 앱의 targetSdkVersion을 "19"이상으로 업데이트하는 경우에만 앱에 영향을 주지만(새 WebView는 "쿼크 모드"로 작동하여 API 레벨 18 이하를 대상으로 하는 앱의 일부 레거시 기능을 제공함), 앱이 이전 버전의 WebView에서 알려지지 않은 동작의 영향을 받을 수도 있습니다.

따라서 기존 앱이 WebView를 사용하는 경우, 가능한 빨리 Android 4.4를 테스트한 다음 Android 4.4에서 WebView로 마이그레이션을 참조하여 targetSdkVersion을 "19" 이상으로 업데이트할 때 앱이 받을 수 있는 영향에 대해 알아보세요.

앱이 AlarmManager를 사용하는 경우...

앱의 targetSdkVersion을 "19" 이상으로 설정하면, set() 또는 setRepeating()을 사용하여 생성하는 알람이 부정확해 집니다.

이제 Android에서는 전원 효율성을 개선하기 위해 모든 앱에서 합리적으로 비슷한 횟수로 발생하는 알람을 함께 일괄 처리하기 때문에, 시스템이 몇 번에 걸치지 않고 한 번에 기기를 깨워 각 알람을 처리합니다.

알람이 정확한 시간과 관련되어 있지 않지만 여전히 특정 시간대(예, 오후 2시~4시)에 알람을 호출하는 것이 중요한 경우, 새 setWindow() 메서드를 사용하여 알람에 대한 "가장 이른" 시간 및 시스템이 알람을 호출해야 하는 가장 이른 시간 이후의 "시간대"를 수락할 수 있습니다.

알람을 정확한 시간에 고정시켜야 하는 경우(예: 캘린더 이벤트 알림), 새 setExact() 메서드를 사용할 수 있습니다.

이러한 정확한 일괄 처리 동작은 업데이트된 앱에만 적용됩니다. targetSdkVersion을 "18" 이하로 설정한 경우, 알람은 이전 버전에서 Android 4.4에서 실행할 때 했던 동작을 계속합니다.

앱이 ContentResolver를 사용하여 데이터를 동기화하는 경우...

앱의 targetSdkVersion을 "19" 이상으로 설정하는 경우, addPeriodicSync()를 사용하여 동기화를 생성하면 지정한 기간의 대략 4%의 기본 가변 간격 내에서 동기화 작업이 수행됩니다. 예를 들어 폴링 빈도가 24시간인 경우, 동기화 작업은 매일 정확히 동일한 시간에 발생하지 않고 매일 대략 1시간의 범위 내에서 발생할 수 있습니다.

동기화 작업을 위한 가변 간격을 지정하려면, 새 requestSync() 메서드를 사용하여 시작해야 합니다. 자세한 내용은 동기화 어댑터에 대한 아래의 섹션을 참조하세요.

이러한 가변 간격 동작은 업데이트된 앱에만 적용됩니다. targetSdkVersion을 "18" 이하로 설정한 경우, 기존 동기화 요청은 이전 버전에서 Android 4.4에서 실행할 때 했던 동작을 계속합니다.

인쇄 프레임워크

Android에는 이제 사용자가 Wi-Fi, 블루투스 또는 다른 서비스를 통해 연결된 프린터를 사용하여 어떤 문서라도 인쇄할 수 있는 완벽한 프레임워크가 포함됩니다. 시스템은 문서를 인쇄하려고 하는 앱과 인쇄 작업을 프린터에 전달하는 서비스 사이의 트랜잭션을 처리합니다. android.print 프레임워크는 인쇄 문서를 지정하여 인쇄할 수 있도록 시스템에 전달하는 데 필요한 모든 API를 제공합니다. 실제로 지정된 인쇄 작업에 필요한 API는 콘텐츠에 따라 다릅니다.

일반 콘텐츠 인쇄

UI의 콘텐츠를 문서로 인쇄하려고 하는 경우, 먼저 PrintDocumentAdapter의 서브클래스를 생성해야 합니다. 이 클래스 내에서 제공된 인쇄 속성에 기반한 레이아웃을 설정하기 위한 onLayout() 및 인쇄 가능한 콘텐츠를 ParcelFileDescriptor에 직렬화하기 위한 onWrite()를 포함해 몇 가지 콜백 메서드를 구현해야 합니다.

콘텐츠를 ParcelFileDescriptor에 쓰려면 PDF에 전달해야 합니다. 새 PdfDocument API는 getCanvas()에서 Canvas를 제공함으로써 이 작업을 편리하게 수행할 수 있는 방법을 제공하며, 이를 통해 인쇄 가능한 콘텐츠를 그릴 수 있습니다. 그런 다음 writeTo() 메서드를 사용하여 PdfDocumentParcelFileDescriptor에 씁니다.

PrintDocumentAdapter에 대한 구현이 정의되면, PrintDocumentAdapter를 인수 중 하나로 선택하는 PrintManager 메서드인 print()를 사용하여 사용자의 요청이 있을 때 인쇄 작업을 수행할 수 있습니다.

이미지 인쇄

사진이나 다른 비트맵을 인쇄하려고 하는 경우, 지원 라이브러리의 도우미가 모든 작업을 자동으로 수행합니다. 간단히 PrintHelper의 새 인스턴스를 생성하고, setScaleMode()로 배율 모드를 설정한 다음 BitmapprintBitmap()에 전달하기만 하면 됩니다. 이게 전부입니다. 라이브러리는 비트맵을 프린터에 전달할 수 있도록 시스템과 이루어지는 나머지 모든 상호작용을 처리합니다.

인쇄 서비스 빌드

프린터 OEM으로 android.printservice 프레임워크를 사용하여 Android 기기에서 프린터와의 상호운용성을 제공합니다. 인쇄 서비스를 사용자가 기기에 설치할 수 있는 APK로 빌드 및 배포할 수 있습니다. 인쇄 서비스 앱은 기본적으로 PrintService 클래스의 서브클래스를 생성함으로써 제목이 없는 클래스로 작동하며, 이 클래스는 시스템에서 인쇄 작업을 받아 적절한 프로토콜을 사용하여 프린터로 전달합니다.

앱 콘텐츠를 인쇄하는 방법에 대한 자세한 내용은 콘텐츠 인쇄를 읽어보세요.

SMS 제공자

앱은 Telephony 콘텐츠 제공자("SMS 제공자")를 이용하여 기기에서 SMS 및 MMS 메시지를 읽고 쓸 수 있습니다. 여기에는 수신, 임시 보관, 전송 및 보류된 SMS 및 MMS 메시지에 대한 테이블이 포함됩니다.

Android 4.4부터는 시스템 설정에서 사용자가 "기본 SMS 앱"을 선택할 수 있습니다. 이를 선택하면, 해당 앱만 SMS 제공자에게 쓸 수 있으며, 기본 SMS 앱만 사용자가 SMS를 수신할 때 SMS_DELIVER_ACTION 브로드캐스트를 수신하거나 사용자가 MMS를 수신할 때 WAP_PUSH_DELIVER_ACTION 브로드캐스트를 수신합니다. 기본 SMS 앱은 새 메시지를 수신하거나 보낼 때 SMS 제공자에게 자세한 내용을 쓰는 역할을 담당합니다.

기본 SMS 앱으로 선택되지 않은 다른 앱은 SMS 제공자를 읽을 수만 있지만 SMS_RECEIVED_ACTION 브로드캐스트를 수신 대기함으로써 새 SMS가 도착할 때 알림을 받을 수도 있습니다. 이 브로드캐스트는 여러 앱에 전달될 수 있는 비중단 브로드캐스트입니다. 이 브로드캐스트는 기본 SMS 앱으로 선택되지 않았지만 전화번호 확인을 수행하는 등 특수한 수신 메시지를 읽어야 하는 앱을 위한 것입니다.

자세한 내용은 블로그 게시물 KitKat를 지원하는 SMS 앱 만들기를 읽어 보세요.

무선 및 연결

호스트 카드 에뮬레이션

Android 앱은 이제 (ISO7816-4에 지정된 바와 같이) 데이터 교환용 APDU를 사용하는 ISO14443-4 (ISO-DEP) NFC 카드를 에뮬레이트할 수 있습니다. 이 작업을 통해 Android 4.4를 실행하는 NFC 지원 기기가 동시에 여러 개의 NFC 카드를 에뮬레이트할 수 있으며, NFC 결제 터미널 또는 다른 NFC 리더가 애플리케이션 식별자(AID)를 기반으로 하는 적절한 NFC 카드로 트랜잭션을 시작할 수 있습니다.

앱에서 이 프로토콜을 사용하고 있는 NFC 카드를 에뮬레이트하려는 경우, HostApduService 클래스를 기반으로 하는 서비스 구성 요소를 생성합니다. 반면에 앱이 대신에 카드 에뮬레이션을 위한 보안 요소를 사용하는 경우, OffHostApduService 클래스를 기반으로 하는 서비스를 생성해야 하며, 이 작업은 트랜잭션에 직접 포함되지 않지만 보안 요소로 처리해야 하는 AID를 등록하는 데 필요합니다.

자세한 내용은 NFC 카드 에뮬레이션 가이드를 읽어보세요.

NFC 리더 모드

새로운 NFC 리더를 이용하면 모든 NFC 액티비티가 포그라운드에 있는 동안 관심을 갖는 태그 유형만 읽도록 액티비티를 제한할 수 있습니다. enableReaderMode()를 사용하여 액티비티에 대한 리더 모드를 활성화하여 새 태그가 감지될 때 콜백을 수신하는 NfcAdapter.ReaderCallback의 구현을 제공할 수 있습니다.

호스트 및 카드 에뮬레이션과 함께 이 새로운 기능을 이용하면 Android가 모바일 결제 인터페이스의 양쪽 말단에서 작동할 수 있습니다. 한 기기는 결제 터미널(리더 모드 액티비티를 실행하는 기기)로 작동하며, 다른 기기는 결제 클라이언트(NFC 카드를 에뮬레이트하는 기기)로 작동합니다.

적외선 송신기

적외선(IR) 송신기를 포함하는 기기에서 실행하는 경우, ConsumerIrManager API를 사용하여 IR 신호를 전송할 수 있습니다. ConsumerIrManager의 인스턴스를 가져오려면, CONSUMER_IR_SERVICE를 인수로 사용하여 getSystemService()를 호출합니다. 그런 다음 getCarrierFrequencies()를 사용하여 기기의 지원되는 IR 주파수를 쿼리하고 transmit()를 사용하여 원하는 주파수와 신호 패턴을 전달함으로써 신호를 전송할 수 있습니다.

항상 먼저 hasIrEmitter()를 호출하여 기기가 IR 송신기를 포함하는지 여부를 확인해야 하지만, 기기가 IR 송신기가 있는 기기하고만 호환되는 경우에는 "android.hardware.consumerir" (FEATURE_CONSUMER_IR)에 대한 매니페스트에 <uses-feature> 요소를 포함해야 합니다.

멀티미디어

적응형 재생

이제 MediaCodec API로 적응형 동영상 재생에 대한 지원을 이용할 수 있고, Surface로 재생하는 동안 해상도를 원활하게 변경할 수 있으며, 새로운 해상도의 디코더 입력 프레임과 출력 버퍼 변경의 해상도를 큰 차이 없이 공급할 수 있습니다.

앱이 코덱에서 필요로 하는 최대 해상도를 지정하는 MediaFormat에 두 개의 키(KEY_MAX_WIDTHKEY_MAX_HEIGHT)를 추가하여 적응형 재생을 활성화할 수 있습니다. MediaFormat에 추가된 이 키를 사용하여 MediaFormatconfigure()와 함께 MediaCodec 인스턴스에 전달합니다.

코덱은 이 값과 동일하거나 이 값보다 작은 해상도 사이에서 원활한 방식으로 전환됩니다. 또한 코덱은 지정된 최대값보다 큰 해상도를 지원할 수 있지만(지원되는 프로필의 범위 안에 있는 경우), 더 큰 해상도로의 전환은 원활하지 않을 수 있습니다.

H.264 동영상을 디코딩하는 동안 해상도를 바꾸려면, MediaCodec.queueInputBuffer()를 사용하여 계속해서 프레임을 큐에 저장하지만 새 SPS(Sequence Parameter Set) 및 PPS(Picture Parameter Set) 값을 단일 버퍼의 IDR(Instantaneous Decoder Refresh) 프레임과 함께 제공하는지 확인해야 합니다.

하지만 적응형 재생에 대한 코덱의 구성을 시도하기 전에 FEATURE_AdaptivePlayback으로 isFeatureSupported(String)를 호출하여 기기가 적응형 재생을 지원하는지 확인해야 합니다.

참고: 적응형 재생에 대한 지원은 공급업체에 따라 다릅니다. 일부 코덱에는 더 많은 해상도 지원을 위해 더 많은 메모리가 필요할 수 있습니다. 따라서 디코딩하는 소스 머티리얼을 기반으로 해상도 최대값을 설정할 수 있습니다.

주문형 오디오 타임스탬프

AudioTimestamp 클래스는 오디오-동영상 동기화를 용이하기 위해 AudioTrack에서 처리하는 오디오 스트림의 특정 "프레임"에 대한 타임라인 세부사항을 제공합니다. 가장 최근의 타임스탬프를 이용할 수 있도록 하려면, AudioTimestamp 객체를 인스턴스화한 후 getTimestamp()에 전달합니다. 타임스탬프에 대한 요청이 성공하면, AudioTrack 인스턴스는 프레임이 표시되거나 표시되도록 약속되는 예상 시간과 함께 프레임 단위의 위치로 채워집니다.

(단조인) AudioTimestamp에서 nanoTime의 값을 사용하여 framePosition에 비해 가장 가깝게 연관된 동영상 프레임을 찾을 수 있으며, 따라서 동영상 프레임을 삭제, 복제 또는 보간하여 오디오와 일치하게 만들 수 있습니다. 또는 nanoTime의 값과 (샘플 속도를 고려한) 향후 동영상 프레임의 예상 시간 사이의 델타 시간을 판별하여 동영상 프레임과 동일한 순간에 예상되는 오디오 프레임을 예측할 수 있습니다.

표면 이미지 리더

ImageReader API는 Surface로 렌더링되기 때문에 이미지 버퍼에 대한 직접 액세스를 제공합니다. 정적 메서드 newInstance()ImageReader를 획득할 수 있습니다. 그런 다음 getSurface()를 호출하여 새 Surface를 생성하고 MediaPlayer 또는 MediaCodec과 같은 프로듀서로 이미지 데이터를 전달합니다. 표면에서 새 이미지를 이용할 수 있을 때 알림을 받으려면, ImageReader.OnImageAvailableListener 인터페이스를 구현하고 setOnImageAvailableListener()에 등록합니다.

이제 Surface에 콘텐츠를 그리면 각 새 이미지 프레임을 이용할 수 있게 될 때 ImageReader.OnImageAvailableListeneronImageAvailable()에 대한 호출을 수신하여 해당 ImageReader를 제공합니다. ImageReader를 사용하여 acquireLatestImage() 또는 acquireNextImage()를 호출하여 프레임의 이미지 데이터를 Image 객체로 획득할 수 있습니다.

Image 객체는 ByteBuffer의 이미지의 타임스탬프, 형식, 크기 및 픽셀 데이터에 대한 직접 액세스를 제공합니다. 하지만 Image 클래스가 이미지를 해석할 수 있도록 하려면, ImageFormat 또는 PixelFormat의 상수로 정의된 유형 중 하나에 따라 형식을 지정해야 합니다.

피크 및 RMS 측정

이제 Visualizer.MeasurementPeakRms의 새 인스턴스를 생성하여 getMeasurementPeakRms()에 전달함으로써 Visualizer의 현재 오디오 스트림에 대한 피크 및 RMS를 쿼리할 수 있습니다. 이 메서드를 호출할 때, 지정된 Visualizer.MeasurementPeakRms의 피크 및 RMS 값은 가장 늦게 측정된 값으로 설정됩니다.

소리 증폭기

LoudnessEnhancerMediaPlayer 또는 AudioTrack의 가청 볼륨을 높일 수 있는 AudioEffect의 새로운 서브클래스입니다. 이는 특히 위에서 언급된 새 getMeasurementPeakRms() 메서드와 함께 다른 미디어가 재생되는 동안 음성 오디오 트랙의 볼륨을 크게 하는 데 유용합니다.

원격 컨트롤러

Android 4.0(API 레벨 14)에서는 미디어 앱이 잠금 화면의 미디어 컨트롤 등 원격 클라이언트에서 미디어 컨트롤러 이벤트를 소모할 수 있는 RemoteControlClient API를 도입했습니다. 이제 새 RemoteController API를 통해 자신만의 원격 컨트롤러를 빌드할 수 있으며, RemoteControlClient와 통합하는 미디어 앱의 재생을 제어할 수 있는 혁신적인 새로운 앱과 주변 기기를 만들 수 있습니다.

원격 컨트롤러를 빌드하려면 자신이 원하는 방법으로 사용자 인터페이스를 구현할 수 있지만, 사용자 미디어 앱에 미디어 버튼 이벤트를 전달하려면 NotificationListenerService 클래스를 확장하고 RemoteController.OnClientUpdateListener 인터페이스를 구현하는 서비스를 생성해야 합니다. NotificationListenerService를 기반으로 사용하는 것은 적절한 프라이버시를 제한할 수 있어서 중요하며, 이를 위해서는 사용자가 시스템 보안 설정 내에서 여러분의 앱을 알림 리스너로 설정해야 합니다.

NotificationListenerService 클래스에는 구현해야 하는 한 쌍의 추상 메서드가 포함되지만, 미디어 재생을 처리하기 위한 미디어 컨트롤러 이벤트만 생각한다면, 이러한 구현을 빈 상태로 두고 대신 RemoteController.OnClientUpdateListener 메서드에 집중할 수 있습니다.

원격 컨트롤러에서 평가

Android 4.4는 사용자가 원격 컨트롤러에서 현재의 트랙을 평가할 수 있는 기능을 추가하여 원격 제어 클라이언트(RemoteControlClient를 포함하는 미디어 컨트롤 이벤트를 수신하는 앱)의 기존 기능을 기반으로 합니다.

Rating 클래스는 사용자 평가에 대한 정보를 캡슐화합니다. 평가는 평가 스타일(RATING_HEART, RATING_THUMB_UP_DOWN, RATING_3_STARS, RATING_4_STARS, RATING_5_STARS 또는 RATING_PERCENTAGE) 및 해당 스타일에 적합한 평점으로 정의할 수 있습니다.

사용자가 원격 컨트롤러에서 트랙을 평가할 수 있도록 하려면:

사용자가 원격 컨트롤러의 평가를 변경할 때 콜백을 받으려면, 새 RemoteControlClient.OnMetadataUpdateListener 인터페이스를 구현하고 인스턴스를 setMetadataUpdateListener()에 전달합니다. 사용자가 평가를 변경할 때 RemoteControlClient.OnMetadataUpdateListeneronMetadataUpdate()에 대한 호출을 수신하며, RATING_KEY_BY_USER를 키로 전달하고 Rating 객체를 값으로 전달합니다.

폐쇄형 자막

VideoView는 이제 HLS(HTTP Live Stream) 동영상을 재생할 때 WebVTT 부제 트랙을 지원하며, 사용자가 시스템 설정에서 정의한 폐쇄형 자막 기본 설정에 따라 부제 트랙을 표시합니다.

또한 addSubtitleSource() 메서드를 사용하여 VideoView에 WebVTT 부제 트랙을 제공할 수 있습니다. 이 메서드는 부제 데이터가 있는 InputStream과 부제 데이터에 대한 형식을 지정하는 MediaFormat 객체를 받아들이며, createSubtitleFormat()을 사용하여 지정할 수 있습니다. 이 부제는 또한 사용자 기본 설정에 따라 동영상 위에 나타납니다.

VideoView를 사용하여 동영상 콘텐츠를 표시하지 않는 경우, 부제 오버레이 사용자의 폐쇄형 자막 기본 설정을 가능한 가깝게 일치하도록 해야 합니다. 새 CaptioningManager API를 이용하면 서체 및 색상 등 CaptioningManager.CaptionStyle을 통해 정의된 스타일을 포함하여 사용자의 폐쇄형 자막 기본 설정을 쿼리할 수 있습니다. 동영상이 이미 시작되었을 때 사용자가 일부 기본 설정을 조정하는 경우, 기본 설정이 변경될 때 콜백을 받아 필요에 따라 부제를 업데이트할 수 있도록 CaptioningManager.CaptioningChangeListener의 인스턴스를 등록하여 기본 설정 변경을 수신 대기해야 합니다.

애니메이션 및 그래픽

장면 및 전환

android.transition 프레임워크는 여러 사용자 인터페이스 상태 간의 애니메이션을 용이하게 하는 API를 제공합니다. 주요 기능은 각 UI에 대한 별도의 레이아웃을 생성하여 "장면"이라고 하는 UI의 특징적인 상태를 정의할 수 있는 기능입니다. 한 장면에서 다른 장면으로 애니메니트하려는 경우, 레이아웃을 현재의 장면에서 다음 장면으로 변경하는 데 필요한 애니메이션을 계산하는 "전환"을 실행합니다.

두 장면 간에 전환하려면, 일반적으로 다음을 수행해야 합니다.

  1. 변경하려고 하는 UI 구성 요소를 포함하는 ViewGroup을 지정합니다.
  2. 변경의 최종 결과(다음 장면)를 표현하는 레이아웃을 지정합니다.
  3. 레이아웃 변경을 애니메이트하는 전환의 유형을 지정합니다.
  4. 전환을 실행합니다.

Scene 객체를 사용하여 1단계와 2단계를 달성할 수 있습니다. Scene에는 장면의 상위 뷰 및 장면의 레이아웃을 비롯하여 전환을 수행하는 데 필요한 레이아웃의 속성을 기술하는 메타데이터가 포함되어 있습니다. 클래스 생성자 또는 정적 메서드 getSceneForLayout()을 사용하여 Scene을 생성할 수 있습니다.

그런 다음 TransitionManager를 사용하여 3단계와 4단계를 달성합니다. 한 가지 방법은 Scene을 정적 메서드인 go()로 전달하는 것입니다. 이를 통해 현재 레이아웃에서 장면의 상위 뷰를 찾고 Scene을 통해 정의된 레이아웃에 도달하기 위해 하위 뷰에서 전환을 수행합니다.

또는 Scene 객체를 생성할 필요는 없지만 대신 beginDelayedTransition()을 호출하여 변경하려는 뷰를 포함한 ViewGroup을 지정할 수 있습니다. 그런 다음 대상 뷰를 추가, 제거 또는 재구성합니다. 시스템이 필요에 따라 변경 사항을 레이아웃한 후, 전환이 시작되어 영향을 받는 모든 뷰를 애니메이트합니다.

추가적인 제어를 위해 프로젝트 res/transition/ 디렉터리에서 XML 파일을 사용하여 사전 정의된 장면 간에 발생하는 전환 집합을 정의할 수 있습니다. <transitionManager> 요소 내에서 각각 장면(레이아웃 파일에 대한 참조)과 해당 장면에 들어가거나 나올 때 적용할 전환을 지정하는 하나 이상의 <transition> 태그를 지정합니다. 그런 다음 inflateTransitionManager()를 사용하여 이러한 전환 집합을 확장합니다. 반환된 TransitionManager를 사용하여 transitionTo()로 각 전환을 실행하고 <transition> 태그 중 하나로 나타나는 Scene을 전달합니다. 또한 TransitionManager API를 사용하여 프로그래밍 방식으로 전환 집합을 정의할 수 있습니다.

전환을 지정할 때, FadeChangeBoundsTransition의 서브클래스로 정의된 일부 사전 정의된 유형을 사용할 수 있습니다. 전환 유형을 지정하지 않으면, 시스템이 기본적으로 AutoTransition을 사용하며, 자동으로 뷰를 사라지게 하고 이동하고 크기를 조정합니다. 또한 이러한 클래스를 확장하여 원하는 애니메이션을 수행하는 사용자 지정 전환을 생성할 수 있습니다. 사용자 지정 전환은 원하는 속성 변경을 추적할 수 있으며 그러한 변경 사항을 기반으로 원하는 애니메이션을 생성할 수 있습니다. 예를 들어 "회전" 속성의 뷰 변경 사항을 수신 대기한 다음 변경 사항을 애니메이트하는 Transition의 서브클래스를 제공할 수 있습니다.

자세한 내용은 TransitionManager 문서를 참조하세요.

애니메이터 일시 중지

이제 Animator API를 이용해 pause()resume() 메서드로 진행 중인 애니메이션을 일시 중지하고 재개할 수 있습니다.

애니메이션의 상태를 추적하기 위해 Animator.AnimatorPauseListener 인터페이스를 구현할 수 있습니다. 이 인터페이스는 애니메이션이 일시 중지 및 재개될 때 pause()resume() 콜백을 제공합니다. 그런 다음 addPauseListener()를 사용하여 Animator 객체에 리스너를 추가합니다.

또는 Animator.AnimatorPauseListener가 정의한 일시 중지 및 재개 콜백에 대한 빈 구현을 포함하는 AnimatorListenerAdapter 추상 클래스의 서브클래스를 생성할 수 있습니다.

재사용 가능한 비트맵

이제 BitmapFactory의 변경 가능한 비트맵을 재사용하여 새 비트맵의 크기가 다른 경우라도 디코딩된 비트맵의 최종 바이트 수(getByteCount()에서 제공)가 재활용된 비트맵의 할당된 바이트 수(getAllocationByteCount()에서 제공) 이하인 한 다른 비트맵을 디코딩할 수 있습니다. 자세한 정보는 inBitmap을 참조하세요.

Bitmap에 대한 새 API는 BitmapFactory의 외부에서 재활용할 수 있도록 유사하게 재구성할 수 있습니다(수동 비트맵 생성 또는 사용자 지정 디코딩 로직의 경우). 이제 setHeight()setWidth()로 비트맵의 크기를 설정할 수 있으며, 기본 비트맵 할당에 영향을 주지 않고 setConfig()로 새 Bitmap.Config를 지정할 수 있습니다. reconfigure() 메서드는 또한 한 번의 호출로 이러한 변경 사항을 결합할 수 있는 편리한 방법을 제공합니다.

하지만 기본 픽셀 버퍼가 예측 가능한 방식으로 다시 매핑되지 않기 때문에 현재 뷰 시스템에서 사용하는 비트맵을 재구성해서는 안 됩니다.

사용자 콘텐츠

저장소 액세스 프레임워크

이전 버전의 Android에서는 여러분의 앱이 다른 앱에서 특정 유형의 파일을 검색하려는 경우, ACTION_GET_CONTENT 액션을 사용하여 인텐트를 호출해야 합니다. 이 액션은 여전히 앱으로 가져오려는 파일을 요청하는 적절한 방법입니다. 하지만 Android 4.4에서는 ACTION_OPEN_DOCUMENT 액션이 도입되어, 사용자가 특정 유형의 파일을 선택하여 파일을 여러분의 앱으로 가져오지 않고도 (아마도 쓰기 액세스 권한을 가진) 해당 파일에 대한 장기 읽기 액세스 권한을 앱에 부여할 수 있습니다.

(클라우드 저장 서비스와 같이) 파일에 대한 저장소 서비스를 제공하는 앱을 개발하는 경우, 콘텐츠 제공자를 새 DocumentsProvider 클래스의 서브클래스로 구현하여 파일을 선택할 수 있는 이 통합 UI에 참여할 수 있습니다. DocumentsProvider의 서브클래스에는 PROVIDER_INTERFACE 액션("android.content.action.DOCUMENTS_PROVIDER")을 받아들이는 인텐트 필터가 포함되어야 합니다. DocumentsProvider에 다음 네 가지 추상 메서드를 구현해야 합니다.

queryRoots()
여기에서는 DocumentsContract.Root에 정의된 열을 사용하여 문서 저장소의 모든 루트 디렉터리를 기술하는 Cursor를 반환해야 합니다.
queryChildDocuments()
여기에서는 DocumentsContract.Document에 정의된 열을 사용하여 지정된 디렉터리의 모든 파일을 기술하는 Cursor를 반환해야 합니다.
queryDocument()
여기에서는 DocumentsContract.Document에 정의된 열을 사용하여 지정된 파일을 기술하는 Cursor를 반환해야 합니다.
openDocument()
여기세서는 지정된 파일을 나타내는 ParcelFileDescriptor를 반환해야 합니다. 사용자가 파일을 선택하고 클라이언트 앱이 openFileDescriptor()를 호출하여 이에 대한 액세스를 요청하면 시스템이 이 메서드를 호출합니다.

자세한 내용은 저장소 액세스 프레임워크 가이드를 참조하세요.

외부 저장소 액세스

이제 기기가 에뮬레이트된 저장소와 SD 카드를 모두 제공하는 경우처럼 보조 외부 저장소 미디어에서 앱 고유의 파일을 읽고 쓸 수 있습니다. 새 메서드 getExternalFilesDirs()File 객체의 배열을 반환하는 경우를 제외하고 기존 getExternalFilesDir() 메서드와 동일하게 작동합니다. 이 메서드가 반환한 경로에 읽거나 쓰기 전에 File 객체를 새 getStorageState() 메서드에 전달하여 현재 저장소를 이용할 수 있는지 여부를 확인합니다.

또한 앱 고유의 디렉터리 및 OBB 디렉터리에 액세스할 수 있는 다른 메서드도 이제 보조 저장소 기기에 대한 액세스를 제공하는 해당 버전이 있습니다(각각 getExternalCacheDirs()getObbDirs()).

반환되는 File 배열의 첫 번째 항목은 기기의 기본 외부 저장소로 간주되며, 이는 getExternalFilesDir() 등의 기존 메서드가 반환하는 File과 동일합니다.

참고: Android 4.4부터는 플랫폼에서 위의 메서드를 사용하여 외부 저장소의 앱 고유 영역에만 액세스해야 하는 경우에 앱이 WRITE_EXTERNAL_STORAGE 또는 READ_EXTERNAL_STORAGE를 획득할 것을 더 이상 요구하지 않습니다. 하지만 getExternalStoragePublicDirectory()를 통해 제공된 외부 저장소의 공유 가능한 영역에 액세스하려는 경우에는 권한이 필요합니다.

동기화 어댑터

ContentResolver의 새 requestSync() 메서드는 새 SyncRequest.Builder를 사용하여 생성할 수 있는 새 SyncRequest 객체의 요청을 캡슐화하여 ContentProvider에 대한 동기화 요청을 정의하는 일부 절차를 간소화합니다. SyncRequest의 속성은 기존 ContentProvider 동기화 호출과 동일한 기능을 제공하지만 setDisallowMetered() 활성화를 통해 네트워크가 측정되는 경우에 동기화를 삭제하도록 지정할 수 있는 기능이 추가됩니다.

사용자 입력

새 센서 유형

TYPE_GEOMAGNETIC_ROTATION_VECTOR 센서는 자기계를 기반으로 하는 회전 벡터 데이터를 제공하며, 이는 자이로스코프를 이용할 수 없거나 일괄 처리된 센서 이벤트와 함께 사용하여 휴대폰이 절전 모드에 있는 동안 기기의 방향을 기록하는 경우에 TYPE_ROTATION_VECTOR 센서에 대한 유용한 대안입니다. 이 센서는 TYPE_ROTATION_VECTOR보다 적은 전원이 필요하지만 이벤트 데이터의 소음이 커질 가능성이 있으며 사용자가 실외에 있을 때 가장 효과적입니다.

이제 Android는 하드웨어에서 다음과 같은 내장 보행 센서도 지원합니다.

TYPE_STEP_DETECTOR
이 센서는 사용자가 한 걸음씩 나아갈 때마다 이벤트를 트리거합니다. 사용자가 한 걸음씩 나아갈 때마다, 이 센서는 1.0의 값과 걸음을 내디디는 때를 나타내는 타임스탬프와 함께 이벤트를 전달합니다.
TYPE_STEP_COUNTER
이 센서도 탐지된 각 걸음에 대한 이벤트를 트리거하지만, 대신에 이 센서는 앱에 처음으로 등록된 이후 누적된 총 걸음 수를 전달합니다.

이 두 개의 보행 센서가 항상 동일한 결과를 전달하는 것은 아닙니다. TYPE_STEP_COUNTER 이벤트의 발생 지연 시간은 TYPE_STEP_DETECTOR의 이벤트보다 높지만, 이는 TYPE_STEP_COUNTER 알고리즘이 긍정 오류(false positive)를 제거하기 위해 더 많은 프로세싱을 거치기 때문입니다. 따라서 TYPE_STEP_COUNTER의 이벤트 전달 속도가 느려질 수 있지만, 그 결과는 더 정확합니다.

두 개의 보행 센서는 모두 하드웨어에 종속되어 있기 때문에(Nexus 5가 이 센서를 지원하는 최초의 기기임) FEATURE_SENSOR_STEP_DETECTORFEATURE_SENSOR_STEP_COUNTER 상수를 사용하여 hasSystemFeature()를 이용할 수 있는지 여부를 확인해야 합니다.

일괄 처리된 센서 이벤트

기기 전원을 보다 잘 관리할 수 있도록 이제 SensorManager API를 통해 시스템이 센서 이벤트 집합을 앱에 전달하는 빈도를 지정할 수 있습니다. 그렇다고 해서 지정된 기간 동안 앱이 이용할 수 있는 실제 센서 이벤트 수가 줄어드는 것은 아니지만, 대신에 시스템이 센서 업데이트를 사용하여 SensorEventListener를 호출하는 빈도가 줄어듭니다. 즉, 시스템이 각 이벤트가 발생하는 순간에 앱에 이벤트를 전달하는 것이 아니라, 일정 기간에 발생하는 모든 이벤트를 저장한 다음 한 번에 앱에 전달합니다.

일괄 처리를 제공하기 위해 SensorManager 클래스는 "최대 보고 지연 시간"을 지정할 수 있는 2가지 버전의 registerListener() 메서드를 추가합니다. 이 새로운 매개변수는 SensorEventListener가 새 센서 이벤트의 전달을 위해 허용하는 최대 지연 시간을 지정합니다. 예를 들어, 1분의 일괄 처리 지연 시간을 지정하는 경우, 시스템은 onSensorChanged() 메서드를 (일괄 처리된 각 이벤트에 대해 한 번씩) 연속 호출하여 1분 미만의 간격으로 최근의 일괄 처리된 이벤트 집합을 전달합니다. 센서 이벤트는 최대 보고 지연 시간 값보다 길게 지연되지는 않지만, 다른 앱이 동일한 센서에 대해 더 짧은 지연 시간을 요청한 경우 더 빨리 도착할 수 있습니다.

하지만, CPU가 깨어 있는 동안에만 보고 지연 시간을 기준으로 일괄 처리된 이벤트를 앱에 전달한다는 점에 유의하세요. 일괄 처리를 지원하는 하드웨어 센서는 CPU가 절전 모드에 있는 동안 계속해서 센서 이벤트를 수집하지만, 앱에 일괄 처리된 이벤트를 전달하기 위해 CPU를 깨우지는 않습니다. 센서가 결국 이벤트에 사용할 수 있는 메모리를 다 사용한 경우 가장 최근의 이벤트를 저장하기 위해 가장 오래된 이벤트를 삭제하기 시작합니다. 센서가 메모리를 가득 채우기 전에 디바이스를 깨우는 방식으로 이벤트 손실을 방지하고, 그런 다음 flush()를 호출하여 가장 최근의 이벤트 집합을 캡처할 수 있습니다. 메모리가 가득 차서 플러시되어야 하는 때를 계산하려면, getFifoMaxEventCount()를 호출하여 저장할 수 있는 센서 이벤트의 최대 수를 가져온 다음 해당 숫자를 앱이 각 이벤트를 원하는 비율로 나눕니다. 이렇게 계산한 값을 사용하여 AlarmManagerService(SensorEventListener를 구현함)를 호출하는 깨우기 알람을 설정하여 센서를 플러시합니다.

참고: 하드웨어 센서의 지원이 필요하기 때문에 모든 기기가 일괄 처리 센서 이벤트를 지원하는 것은 아닙니다. 하지만 기기가 일괄 처리를 지원하지 않는 경우, 시스템이 일괄 처리 지연 시간 인수를 무시하고 실시간으로 센서 이벤트를 전달하기 때문에, Android 4.4부터는 항상 새 registerListener() 메서드를 사용해야 합니다.

컨트롤러 ID

Android는 이제 getControllerNumber()로 쿼리할 수 있는 고유한 정수를 사용하여 연결된 각 컨트롤러를 식별하며, 따라서 보다 쉽게 각 컨트롤러를 게임의 다른 플레이어와 연관시킬 수 있습니다. 사용자가 컨트롤러를 분리, 연결 또는 재구성하기 때문에 각 컨트롤러의 번호가 바뀔 수 있으며, 따라서 InputManager.InputDeviceListener의 인스턴스를 등록하여 컨트롤러가 각 입력 기기와 일치하는지 확인해야 합니다. 그런 다음 컨트롤러의 번호가 변경되면 각 InputDevice에 대해 getControllerNumber()를 호출합니다.

연결된 기기는 또한 getProductId()getVendorId()에서 이용할 수 있는 제품 및 공급업체 ID도 제공합니다. 기기에서 이용할 수 있는 키 세트를 기준으로 키 매핑을 수정해야 하는 경우, 기기를 쿼리하여 hasKeys(int...)로 특정 키를 이용할 수 있는지 여부를 확인할 수 있습니다.

사용자 인터페이스

몰입형 전체 화면 모드

앱에 전체 화면을 채우는 레이아웃을 제공하기 위해 setSystemUiVisibility()의 새 SYSTEM_UI_FLAG_IMMERSIVE 플래그는 (SYSTEM_UI_FLAG_HIDE_NAVIGATION와 결합된 경우) 새 몰입형 전체 화면 모드를 활성화합니다. 몰입형 전체 화면 모드가 활성화되면, 액티비티가 계속해서 모든 터치 이벤트를 수신합니다. 사용자는 시스템 바가 정상적으로 나타나는 지역을 따라 내부 스와이프를 사용하여 시스템 바를 표시할 수 있습니다. 이렇게 하면 SYSTEM_UI_FLAG_HIDE_NAVIGATION 플래그 (및 해당되는 경우 SYSTEM_UI_FLAG_FULLSCREEN 플래그)가 삭제되기 때문에 시스템 바가 계속해서 표시됩니다. 하지만 잠시 후에 시스템 바를 다시 감추려고 하는 경우에는 SYSTEM_UI_FLAG_IMMERSIVE_STICKY 플래그를 대신 사용할 수 있습니다.

반투명 시스템 바

이제 새로운 테마인 Theme.Holo.NoActionBar.TranslucentDecorTheme.Holo.Light.NoActionBar.TranslucentDecor로 시스템 바를 부분적으로 반투명으로 만들 수 있습니다. 반투명 시스템 바를 활성화하면 레이아웃이 시스템 바의 뒤에 있는 영역을 채우므로, 따라서 레이아웃 중에서 시스템 바로 덮여서는 안되는 부분에 대해 fitsSystemWindows를 활성화해야 합니다.

사용자 지정 테마를 생성하는 경우, 이 테마 중 하나를 상위 테마로 설정하거나 windowTranslucentNavigationwindowTranslucentStatus 스타일 속성을 테마에 포함합니다.

향상된 알림 리스너

Android 4.3에서는 NotificationListenerService API를 추가하여 앱이 시스템이 게시하는 새로운 알림에 대한 정보를 수신할 수 있습니다. Android 4.4에서는 알림 리스너가 알림에 대한 추가 메타데이터 및 알림의 액션에 대한 전체 내용을 검색할 수 있습니다.

Notification.extras 필드에는 Bundle이 포함되어 EXTRA_TITLEEXTRA_PICTURE 등의 알림 빌더 추가 메타데이터를 전달합니다. 새 Notification.Action 클래스는 알림에 첨부되어 새 actions 필드에서 검색할 수 있는 액션의 특성을 정의합니다.

RTL 레이아웃에 대한 드로어블 미러링

이전 버전의 Android에서는 앱이 오른쪽에서 왼쪽 방향의 레이아웃을 가로 방향으로 반전시켜야 하는 이미지를 포함하는 경우, drawables-ldrtl/ 리소스 디렉터리에 미러링된 이미지를 포함해야 합니다. 이제 시스템이 자동으로 autoMirrored 속성을 활성화하거나 setAutoMirrored()를 호출하여 이미지를 미러링할 수 있습니다. 활성화되면 레이아웃 방향이 오른쪽에서 왼쪽일 때 Drawable이 자동으로 미러링됩니다.

접근성

이제 View 클래스를 통해 accessibilityLiveRegion 속성을 XML 레이아웃에 추가하거나 setAccessibilityLiveRegion()을 호출하여 UI 중에서 새로운 텍스트 콘텐츠로 동적으로 업데이트되는 부분에 대해 "라이브 지역"을 선언할 수 있습니다. 예를 들어, "잘못된 비밀번호" 알림을 표시하는 텍스트 필드가 포함된 로그인 화면은 라이브 지역으로 표시되어야 하며, 따라서 스크린 리더는 화면이 변경되면 메시지를 다시 표시합니다.

이제 접근성 서비스를 제공하는 앱은 또한 AccessibilityNodeInfo.CollectionInfoAccessibilityNodeInfo.CollectionItemInfo를 사용하여 목록 또는 그리드 뷰 등의 뷰 콜렉션에 대한 정보를 제공하는 새 API로 기능을 확장할 수 있습니다.

앱 권한

다음은 앱이 특정 새 API를 사용하기 위해 <uses-permission> 태그를 사용하여 요청해야 하는 새 권한입니다.

INSTALL_SHORTCUT
애플리케이션이 런처에 단축키를 설치할 수 있습니다.
UNINSTALL_SHORTCUT
애플리케이션이 런처에서 단축키를 제거할 수 있습니다.
TRANSMIT_IR
애플리케이션이 기기의 IR 송신기(가능한 경우)를 사용할 수 있습니다.

참고: Android 4.4부터는 getExternalFilesDir() 등의 메서드를 사용하여 외부 저장소의 앱 고유 영역에 액세스하려고 하는 경우에 플랫폼에서 더 이상 앱이 WRITE_EXTERNAL_STORAGE 또는 READ_EXTERNAL_STORAGE를 획득할 것을 요구하지 않습니다. 하지만 getExternalStoragePublicDirectory()를 통해 제공된 외부 저장소의 공유 가능한 영역에 액세스하려는 경우에는 여전히 권한이 필요합니다.

기기 기능

다음은 <uses-feature> 태그로 선언하여 Google Play에서 앱 요구사항을 선언하고 필터링을 활성화하거나 런타임에 확인할 수 있는 새 기기 기능입니다.

FEATURE_CONSUMER_IR
기기가 소비자 IR 기기와 통신을 할 수 있습니다.
FEATURE_DEVICE_ADMIN
기기가 기기 관리자를 통해 기기 정책 적용을 지원합니다.
FEATURE_NFC_HOST_CARD_EMULATION
기기가 호스트 기반 NFC 카드 에뮬레이션을 지원합니다.
FEATURE_SENSOR_STEP_COUNTER
기기에 하드웨어 보행 계수기가 포함됩니다.
FEATURE_SENSOR_STEP_DETECTOR
기기에 하드웨어 보행 탐지기가 포함됩니다.

Android 4.4의 모든 API 변경 사항에 대한 상세한 정보는 API 차이점 보고서를 참조하세요.