API 수준: 19
Android 4.4 (KITKAT
)는 사용자와 앱 개발자에게 새로운 기능을 제공하는 Android 플랫폼의 새로운 버전입니다. 이 문서에서는 가장 주목할 새로운 API를 소개합니다.
앱 개발자는 최대한 빨리 SDK Manager에서 Android 4.4 시스템 이미지와 SDK 플랫폼을 다운로드해야 합니다. 앱을 테스트할 Android 4.4를 실행하는 기기가 없는 경우 Android 4.4 시스템 이미지를 사용하여 Android 에뮬레이터에서 앱을 테스트합니다. 그런 다음 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에서 테스트하고 targetSdkVersion
를 '19' 이상으로 업데이트할 때 앱에 미칠 수 있는 영향에 관한 자세한 내용은 Android 4.4에서 WebView로 이전을 참고하세요.
앱이 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()
메서드를 사용하여 PdfDocument
를 ParcelFileDescriptor
에 씁니다.
PrintDocumentAdapter
의 구현을 정의한 후에는 PrintDocumentAdapter
를 인수 중 하나로 사용하는 PrintManager
메서드 print()
를 사용하여 사용자 요청 시 인쇄 작업을 실행할 수 있습니다.
이미지 인쇄
사진이나 다른 비트맵을 인쇄하려고 하는 경우, 지원 라이브러리의 도우미가 모든 작업을 자동으로 수행합니다. PrintHelper
의 새 인스턴스를 만들고 setScaleMode()
로 크기 조정 모드를 설정한 다음 Bitmap
를 printBitmap()
에 전달하기만 하면 됩니다. 이상입니다. 라이브러리는 비트맵을 프린터에 전달할 수 있도록 시스템과 이루어지는 나머지 모든 상호작용을 처리합니다.
인쇄 서비스 빌드
프린터 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를 수신할 때 기본 SMS 앱만 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_WIDTH
및 KEY_MAX_HEIGHT
)를 추가하여 적응형 재생을 사용 설정할 수 있습니다. MediaFormat
에 추가한 후 configure()
를 사용하여 MediaFormat
를 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.OnImageAvailableListener
는 새 이미지 프레임이 제공될 때마다 onImageAvailable()
호출을 수신하여 상응하는 ImageReader
를 제공합니다. ImageReader
를 사용하여 acquireLatestImage()
또는 acquireNextImage()
를 호출하여 프레임의 이미지 데이터를 Image
객체로 획득할 수 있습니다.
Image
객체는 ByteBuffer
의 이미지 타임스탬프, 형식, 크기, 픽셀 데이터에 직접 액세스할 수 있도록 합니다. 그러나 Image
클래스가 이미지를 해석하려면 이미지가 ImageFormat
또는 PixelFormat
의 상수로 정의된 유형 중 하나에 따라 형식이 지정되어야 합니다.
피크 및 RMS 측정
이제 Visualizer.MeasurementPeakRms
의 새 인스턴스를 만들어 getMeasurementPeakRms()
에 전달하여 Visualizer
에서 현재 오디오 스트림의 최대값과 RMS를 쿼리할 수 있습니다. 이 메서드를 호출하면 지정된 Visualizer.MeasurementPeakRms
의 최대값과 RMS 값이 최근 측정값으로 설정됩니다.
소리 증폭기
LoudnessEnhancer
는 MediaPlayer
또는 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
)과 해당 스타일에 적합한 평점 값으로 정의됩니다.
사용자가 원격 컨트롤러에서 트랙을 평가할 수 있도록 하려면:
-
setTransportControlFlags()
에FLAG_KEY_MEDIA_RATING
플래그를 추가하여 사용자에게 평점 UI를 노출하려고 함을 알립니다 (해당하는 경우). editMetadata()
를 호출하여RemoteControlClient.MetadataEditor
를 가져오고addEditableKey()
와 함께RATING_KEY_BY_USER
에 전달합니다.- 그런 다음
putObject()
를 호출하고RATING_KEY_BY_USER
를 키로, 위의 평가 스타일 중 하나를 값으로 전달하여 평가 스타일을 지정합니다.
사용자가 리모컨에서 평점을 변경할 때 콜백을 수신하려면 새 RemoteControlClient.OnMetadataUpdateListener
인터페이스를 구현하고 인스턴스를 setMetadataUpdateListener()
에 전달합니다. 사용자가 평점을 변경하면 RemoteControlClient.OnMetadataUpdateListener
는 onMetadataUpdate()
호출을 수신하여 RATING_KEY_BY_USER
를 키로, Rating
객체를 값으로 전달합니다.
자막
이제 VideoView
에서 HTTP 라이브 스트림 (HLS) 동영상을 재생할 때 WebVTT 자막 트랙을 지원하여 사용자가 시스템 설정에서 정의한 자막 환경설정에 따라 자막 트랙을 표시합니다.
addSubtitleSource()
메서드를 사용하여 WebVTT 자막 트랙을 VideoView
에 제공할 수도 있습니다. 이 메서드는 자막 데이터를 전송하는 InputStream
와 자막 데이터의 형식을 지정하는 MediaFormat
객체를 허용하며, 이 형식은 createSubtitleFormat()
를 사용하여 지정할 수 있습니다. 이러한 자막은 사용자의 환경설정에 따라 동영상 위에 표시됩니다.
VideoView
를 사용하여 동영상 콘텐츠를 표시하지 않는 경우 자막 오버레이를 사용자의 자막 방송 환경설정에 최대한 가깝게 맞춰야 합니다. 새로운 CaptioningManager
API를 사용하면 서체 및 색상과 같이 CaptioningManager.CaptionStyle
에 의해 정의된 스타일을 비롯한 사용자의 자막 환경설정을 쿼리할 수 있습니다. 동영상이 이미 시작된 후에 사용자가 일부 환경설정을 조정하는 경우 CaptioningManager.CaptioningChangeListener
인스턴스를 등록하여 환경설정이 변경될 때 콜백을 수신한 후 환경설정 변경사항을 리슨하고 필요에 따라 자막을 업데이트해야 합니다.
애니메이션 및 그래픽
장면 및 전환
새로운 android.transition
프레임워크는 사용자 인터페이스의 여러 상태 간에 애니메이션을 쉽게 지원하는 API를 제공합니다. 주요 기능은 '장면'이라고 하는 UI의 고유한 상태를 정의할 수 있는 기능으로, 각 상태에 대해 별도의 레이아웃을 만들 수 있습니다. 한 장면에서 다른 장면으로 애니메이션을 적용하려면 '전환'을 실행합니다. 전환은 현재 장면에서 다음 장면으로 레이아웃을 변경하는 데 필요한 애니메이션을 계산합니다.
두 장면 간에 전환하려면, 일반적으로 다음을 수행해야 합니다.
- 변경하려는 UI 구성요소가 포함된
ViewGroup
를 지정합니다. - 변경의 최종 결과(다음 장면)를 표현하는 레이아웃을 지정합니다.
- 레이아웃 변경을 애니메이트하는 전환의 유형을 지정합니다.
- 전환을 실행합니다.
Scene
객체를 사용하여 1단계와 2단계를 실행할 수 있습니다. Scene
에는 장면의 상위 뷰와 장면의 레이아웃을 비롯하여 전환을 실행하는 데 필요한 레이아웃 속성을 설명하는 메타데이터가 포함됩니다. 클래스 생성자 또는 정적 메서드 getSceneForLayout()
를 사용하여 Scene
를 만들 수 있습니다.
그런 다음 TransitionManager
를 사용하여 3단계와 4단계를 완료해야 합니다. 한 가지 방법은 Scene
를 정적 메서드 go()
에 전달하는 것입니다. 이렇게 하면 현재 레이아웃에서 장면의 상위 뷰가 발견되고 Scene
로 정의된 레이아웃에 도달하기 위해 하위 뷰에서 전환이 실행됩니다.
또는 Scene
객체를 전혀 만들지 않고 대신 beginDelayedTransition()
를 호출하여 변경하려는 뷰가 포함된 ViewGroup
를 지정할 수 있습니다. 그런 다음 대상 뷰를 추가, 제거 또는 재구성합니다. 시스템이 필요에 따라 변경 사항을 레이아웃한 후, 전환이 시작되어 영향을 받는 모든 뷰를 애니메이트합니다.
추가 제어를 위해 프로젝트 res/transition/
디렉터리의 XML 파일을 사용하여 사전 정의된 장면 간에 발생해야 하는 전환 세트를 정의할 수 있습니다. <transitionManager>
요소 내에서 장면 (레이아웃 파일 참조)과 해당 장면에 진입하거나 종료할 때 적용할 전환을 각각 지정하는 <transition>
태그를 하나 이상 지정합니다. 그런 다음 inflateTransitionManager()
를 사용하여 이 전환 집합을 확장합니다. 반환된 TransitionManager
를 사용하여 <transition>
태그 중 하나로 표현되는 Scene
를 전달하여 transitionTo()
로 각 전환을 실행합니다. TransitionManager
API를 사용하여 전환 집합을 프로그래매틱 방식으로 정의할 수도 있습니다.
전환을 지정할 때 Transition
의 서브클래스(예: Fade
, ChangeBounds
)에 의해 정의된 여러 사전 정의된 유형을 사용할 수 있습니다. 전환 유형을 지정하지 않으면 시스템은 기본적으로 AutoTransition
를 사용하여 필요에 따라 뷰를 자동으로 페이드 처리, 이동, 크기 조절합니다. 또한 이러한 클래스를 확장하여 원하는 대로 애니메이션을 실행하여 맞춤 전환을 만들 수 있습니다. 맞춤 전환은 원하는 속성 변경사항을 추적하고 이러한 변경사항을 기반으로 원하는 애니메이션을 만들 수 있습니다. 예를 들어 뷰의 'rotation' 속성 변경사항을 수신 대기한 다음 변경사항에 애니메이션을 적용하는 Transition
의 서브클래스를 제공할 수 있습니다.
자세한 내용은 TransitionManager
문서를 참고하세요.
애니메이터 일시 중지
이제 Animator
API를 사용하면 pause()
및 resume()
메서드로 진행 중인 애니메이션을 일시중지하고 재개할 수 있습니다.
애니메이션의 상태를 추적하려면 애니메이션이 일시중지되고 다시 시작될 때 콜백(pause()
및 resume()
)을 제공하는 Animator.AnimatorPauseListener
인터페이스를 구현하면 됩니다. 그런 다음 addPauseListener()
를 사용하여 Animator
객체에 리스너를 추가합니다.
또는 AnimatorListenerAdapter
추상 클래스의 서브클래스를 만들 수 있습니다. 이제 이 클래스에는 Animator.AnimatorPauseListener
로 정의된 일시중지 및 재개 콜백의 빈 구현이 포함됩니다.
재사용 가능한 비트맵
이제 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
알고리즘이 거짓양성을 제거하기 위해 더 많은 처리를 하기 때문입니다. 따라서 TYPE_STEP_COUNTER
는 이벤트를 전달하는 속도가 느릴 수 있지만 결과는 더 정확합니다.
두 걸음 수 센서는 하드웨어에 종속되므로 (Nexus 5가 이를 지원하는 최초의 기기임) FEATURE_SENSOR_STEP_DETECTOR
및 FEATURE_SENSOR_STEP_COUNTER
상수를 사용하여 hasSystemFeature()
로 가용성을 확인해야 합니다.
일괄 처리된 센서 이벤트
이제 SensorManager
API를 사용하면 기기 전력을 더 효과적으로 관리할 수 있습니다. 시스템이 앱에 센서 이벤트 일괄을 전송하는 빈도를 지정할 수 있습니다. 이렇게 하면 특정 기간 동안 앱에서 사용할 수 있는 실제 센서 이벤트 수가 줄어들지 않고 대신 시스템이 센서 업데이트와 함께 SensorEventListener
를 호출하는 빈도가 줄어듭니다. 즉, 시스템이 각 이벤트가 발생하는 순간에 앱에 이벤트를 전달하는 것이 아니라, 일정 기간에 발생하는 모든 이벤트를 저장한 다음 한 번에 앱에 전달합니다.
일괄 처리를 제공하기 위해 SensorManager
클래스는 '최대 보고 지연 시간'을 지정할 수 있는 registerListener()
메서드의 두 가지 새 버전을 추가합니다. 이 새 매개변수는 SensorEventListener
가 새 센서 이벤트를 전송할 때 허용할 수 있는 최대 지연 시간을 지정합니다. 예를 들어 일괄 지연 시간을 1분으로 지정하면 시스템은 일괄 처리된 각 이벤트에 대해 onSensorChanged()
메서드를 한 번씩 연속으로 호출하여 1분 이내 간격으로 최근 일괄 처리된 이벤트 세트를 전송합니다. 센서 이벤트는 최대 보고 지연 시간 값보다 길게 지연되지는 않지만, 다른 앱이 동일한 센서에 대해 더 짧은 지연 시간을 요청한 경우 더 빨리 도착할 수 있습니다.
그러나 센서는 CPU가 깨어 있는 동안에만 보고 지연 시간을 기반으로 앱에 일괄 이벤트를 전송합니다. 일괄 처리를 지원하는 하드웨어 센서는 CPU가 절전 모드에 있는 동안 계속해서 센서 이벤트를 수집하지만, 앱에 일괄 처리된 이벤트를 전달하기 위해 CPU를 깨우지는 않습니다. 센서가 결국 이벤트에 사용할 수 있는 메모리를 다 사용한 경우 가장 최근의 이벤트를 저장하기 위해 가장 오래된 이벤트를 삭제하기 시작합니다. 센서가 메모리를 채우기 전에 기기를 깨운 다음 flush()
를 호출하여 최신 일괄 이벤트를 캡처하면 이벤트 손실을 방지할 수 있습니다. 메모리가 가득 차 플러시해야 하는 시점을 추정하려면 getFifoMaxEventCount()
를 호출하여 저장할 수 있는 최대 센서 이벤트 수를 가져오고 이 수를 앱에서 각 이벤트를 원하는 속도로 나눕니다. 이 계산을 사용하여 AlarmManager
로 Service
(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.TranslucentDecor
및 Theme.Holo.Light.NoActionBar.TranslucentDecor
를 사용하여 시스템 표시줄을 부분적으로 반투명하게 만들 수 있습니다. 투명한 시스템 표시줄을 사용 설정하면 레이아웃이 시스템 표시줄 뒤의 영역을 채우므로 시스템 표시줄로 가려져서는 안 되는 레이아웃 부분에도 fitsSystemWindows
를 사용 설정해야 합니다.
맞춤 테마를 만드는 경우 이러한 테마 중 하나를 상위 테마로 설정하거나 테마에 windowTranslucentNavigation
및 windowTranslucentStatus
스타일 속성을 포함합니다.
향상된 알림 리스너
Android 4.3에서는 NotificationListenerService
API를 추가하여 앱이 시스템에서 게시하는 새 알림에 관한 정보를 수신할 수 있도록 했습니다. Android 4.4에서는 알림 리스너가 알림의 추가 메타데이터를 검색하고 알림 작업에 관한 세부정보를 완료할 수 있습니다.
새 Notification.extras
필드에는 알림 빌더에 EXTRA_TITLE
및 EXTRA_PICTURE
와 같은 추가 메타데이터를 전송하는 Bundle
가 포함되어 있습니다.
새 Notification.Action
클래스는 알림에 연결된 작업의 특성을 정의하며, 이 특성은 새 actions
필드에서 가져올 수 있습니다.
RTL 레이아웃에 대한 드로어블 미러링
이전 버전의 Android에서 앱에 오른쪽에서 왼쪽 레이아웃을 위해 가로 방향을 반전해야 하는 이미지가 포함된 경우 drawables-ldrtl/
리소스 디렉터리에 미러링된 이미지를 포함해야 합니다. 이제 시스템은 드로어블 리소스에서 autoMirrored
속성을 사용 설정하거나 setAutoMirrored()
를 호출하여 이미지를 자동으로 미러링할 수 있습니다. 사용 설정하면 레이아웃 방향이 오른쪽에서 왼쪽일 때 Drawable
가 자동으로 미러링됩니다.
접근성
이제 View
클래스를 사용하면 XML 레이아웃에 새 accessibilityLiveRegion
속성을 추가하거나 setAccessibilityLiveRegion()
를 호출하여 새 텍스트 콘텐츠로 동적으로 업데이트되는 UI 부분의 '실시간 영역'을 선언할 수 있습니다. 예를 들어 '잘못된 비밀번호' 알림을 표시하는 텍스트 필드가 있는 로그인 화면은 라이브 영역으로 표시되어야 스크린 리더가 메시지가 변경될 때 메시지를 읽어줍니다.
접근성 서비스를 제공하는 앱은 이제 AccessibilityNodeInfo.CollectionInfo
및 AccessibilityNodeInfo.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
- 기기가 소비자용 적외선 기기와 통신할 수 있습니다.
FEATURE_DEVICE_ADMIN
- 기기가 기기 관리자를 통한 기기 정책 시행을 지원합니다.
FEATURE_NFC_HOST_CARD_EMULATION
- 기기가 호스트 기반 NFC 카드 에뮬레이션을 지원합니다.
FEATURE_SENSOR_STEP_COUNTER
- 기기에 하드웨어 보행 계수기가 포함되어 있습니다.
FEATURE_SENSOR_STEP_DETECTOR
- 기기에 하드웨어 걸음 감지기가 포함되어 있습니다.
Android 4.4의 모든 API 변경사항을 자세히 보려면 API 차이점 보고서를 참고하세요.