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 Emulator에서 앱을 테스트합니다. 그런 다음 Android 4.4 플랫폼에서 앱을 빌드하여 최신 API를 사용할 수 있습니다.

대상 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() 메서드를 사용하여 ParcelFileDescriptorPdfDocument를 작성합니다.

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 앱만 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로 재생하는 동안 해상도를 원활하게 변경할 수 있습니다. 이렇게 하면 새로운 해상도의 디코더 입력 프레임과 출력 버퍼 변경의 해상도를 큰 차이 없이 제공할 수 있습니다.

앱이 코덱에서 요구하는 최대 해상도를 지정하는 두 개의 키(KEY_MAX_WIDTHKEY_MAX_HEIGHT)를 MediaFormat에 추가하여 적응형 재생을 사용 설정할 수 있습니다. MediaFormat에 추가한 다음 configure()를 사용하여 MediaFormatMediaCodec 인스턴스에 전달합니다.

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

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

그러나 적응형 재생의 코덱을 구성하기 전에 FEATURE_AdaptivePlaybackisFeatureSupported(String)를 호출하여 기기가 적응형 재생을 지원하는지 확인해야 합니다.

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

주문형 오디오 타임스탬프

오디오-동영상 동기화를 용이하게 하기 위해 새 AudioTimestamp 클래스는 AudioTrack에서 처리하는 오디오 스트림의 특정 '프레임'에 관한 타임라인 세부정보를 제공합니다. 사용 가능한 최신 타임스탬프를 가져오려면 AudioTimestamp 객체를 인스턴스화하여 getTimestamp()에 전달합니다. 타임스탬프 요청이 성공하면 AudioTrack 인스턴스는 프레임이 표시되거나 표시되도록 커밋된 예상 시간과 함께 프레임 단위의 위치로 채워집니다.

AudioTimestampnanoTime 값 (단조)을 사용하여 framePosition와 비교하여 가장 가까운 관련 동영상 프레임을 찾을 수 있으므로 동영상 프레임을 삭제, 복제 또는 보간하여 오디오와 일치시킬 수 있습니다. 또는 nanoTime 값과 향후 동영상 프레임의 예상 시간 (샘플링 레이트를 고려) 사이의 델타 시간을 확인하여 동영상 프레임과 동일한 순간에 예상되는 오디오 프레임을 예측할 수 있습니다.

표면 이미지 리더

ImageReader API를 사용하면 이미지 버퍼가 Surface로 렌더링될 때 이미지 버퍼에 직접 액세스할 수 있습니다. 정적 메서드 newInstance()ImageReader를 획득할 수 있습니다. 그런 다음 getSurface()를 호출하여 새 Surface를 만들고 MediaPlayer 또는 MediaCodec와 같은 생산자를 사용하여 이미지 데이터를 전달합니다. 노출 영역에서 새 이미지를 사용할 수 있을 때 알림을 받으려면 ImageReader.OnImageAvailableListener 인터페이스를 구현하고 setOnImageAvailableListener()로 등록합니다.

이제 Surface에 콘텐츠를 그리면 ImageReader.OnImageAvailableListener는 각각의 새 이미지 프레임을 사용할 수 있게 되면 onImageAvailable() 호출을 수신하여 상응하는 ImageReader를 제공합니다. acquireLatestImage() 또는 acquireNextImage()를 호출하여 ImageReader를 사용하여 프레임의 이미지 데이터를 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에서 HTTP 실시간 스트림 (HLS) 동영상을 재생할 때 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를 사용하여 프로그래매틱 방식으로 전환 집합을 정의할 수도 있습니다.

전환을 지정할 때 FadeChangeBounds와 같이 Transition의 서브클래스로 정의된 여러 사전 정의된 유형을 사용할 수 있습니다. 전환 유형을 지정하지 않으면 시스템은 기본적으로 AutoTransition를 사용하여 필요에 따라 뷰를 자동으로 페이드 아웃하고 이동하고 크기를 조정합니다. 또한 이러한 클래스를 확장하여 원하는 애니메이션을 수행하도록 사용자 지정 전환을 만들 수 있습니다. 사용자 지정 전환은 원하는 속성 변경 사항을 추적할 수 있고 그러한 변경 사항을 기반으로 원하는 애니메이션을 만들 수 있습니다. 예를 들어 뷰의 '회전' 속성 변경사항을 수신 대기한 후 변경사항에 애니메이션을 적용하는 Transition의 서브클래스를 제공할 수 있습니다.

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

애니메이터 일시 중지

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

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

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

재사용 가능한 비트맵

이제 디코딩된 비트맵 (getByteCount()에서 사용 가능)의 결과 바이트 수가 재사용된 비트맵 (getAllocationByteCount()에서 제공)의 할당된 바이트 수보다 작거나 같은 경우, 이제 새 비트맵의 크기가 다른 경우에도 BitmapFactory의 변경 가능한 비트맵을 재사용하여 다른 비트맵을 디코딩할 수 있습니다. 자세한 내용은 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에서 추상 메서드 4개를 구현해야 합니다.

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 알고리즘이 거짓양성을 제거하기 위해 더 많은 처리를 수행하기 때문입니다. 따라서 TYPE_STEP_COUNTER의 이벤트 전달 속도가 느려질 수 있지만 결과는 더 정확합니다.

두 보행 센서는 모두 하드웨어에 따라 달라지므로 (Nexus 5가 이 센서를 지원하는 첫 번째 기기임) FEATURE_SENSOR_STEP_DETECTORFEATURE_SENSOR_STEP_COUNTER 상수를 사용하여 hasSystemFeature()의 사용 가능 여부를 확인해야 합니다.

일괄 처리된 센서 이벤트

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

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

하지만 센서는 CPU가 깨어 있는 동안에만 보고 지연 시간을 기반으로 일괄 처리된 이벤트를 앱에 전달합니다. 일괄 처리를 지원하는 하드웨어 센서는 CPU가 절전 모드에 있는 동안 계속해서 센서 이벤트를 수집하지만, 앱에 일괄 처리된 이벤트를 전달하기 위해 CPU를 깨우지는 않습니다. 센서가 결국 이벤트에 사용할 수 있는 메모리를 다 사용한 경우 가장 최근의 이벤트를 저장하기 위해 가장 오래된 이벤트를 삭제하기 시작합니다. 센서가 메모리를 채우기 전에 기기의 절전 모드를 해제한 다음 flush()를 호출하여 최신 이벤트 배치를 캡처하면 이벤트 손실을 방지할 수 있습니다. 메모리가 가득 차서 플러시되어야 하는 시점을 추정하려면 getFifoMaxEventCount()를 호출하여 저장할 수 있는 센서 이벤트의 최대 개수를 가져오고 이 숫자를 앱에서 각 이벤트에 원하는 속도로 나눕니다. 이 계산에 따라 Service (SensorEventListener 구현)를 호출하여 센서를 플러시하는 AlarmManager로 절전 모드 알람을 설정합니다.

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

컨트롤러 ID

이제 Android는 getControllerNumber()로 쿼리할 수 있는 고유한 정수로 연결된 각 컨트롤러를 식별하므로 각 컨트롤러를 게임의 다른 플레이어와 더 쉽게 연결할 수 있습니다. 사용자가 컨트롤러의 연결 해제, 연결 또는 재구성으로 인해 각 컨트롤러의 번호가 변경될 수 있으므로 InputManager.InputDeviceListener 인스턴스를 등록하여 각 입력 장치에 해당하는 컨트롤러 번호를 추적해야 합니다. 그런 다음 변경이 발생하면 각 InputDevicegetControllerNumber()를 호출합니다.

또한 이제 연결된 기기에서 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 필드에는 알림 빌더 추가 메타데이터(예: EXTRA_TITLEEXTRA_PICTURE)를 전달하는 Bundle가 포함됩니다. 새로운 Notification.Action 클래스는 알림에 첨부된 작업의 특성을 정의하며, 이 특성은 새 actions 필드에서 검색할 수 있습니다.

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

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

접근성

이제 View 클래스를 사용하면 XML 레이아웃에 새 accessibilityLiveRegion 속성을 추가하거나 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 차이 보고서를 참고하세요.