Android 8.0에는 사용자와 개발자를 위한 새로운 다양한 기능이 도입되었습니다. 이 문서에서는 개발자를 위한 새로운 기능을 소개합니다.
Android 8.0 동작 변경 사항에서 플랫폼 변경이 앱에 영향을 줄 수 있는 분야에 대해 알아보세요.
사용자 환경
알림
Android8.0 O에서는 알림 동작과 설정을 더욱 간편하고 일관적으로 관리할 수 있도록 알림을 재구성했습니다. 변경 사항은 다음과 같습니다.
- 알림 채널: Android 8.0에서는 알림 채널이 도입됩니다. 알림 채널은 개발자가 표시하고자 하는 각 유형의 알림에 대해 사용자 맞춤형 채널을 생성합니다. 사용자 인터페이스에서는 알림 채널을 알림 범주라고 부릅니다. 알림을 구현하는 자세한 방법은 알림 채널 가이드를 참조하세요.
- 알림 배지: Android 8.0에서는 알림 배지를 앱 런처 아이콘에 표시하도록 지원합니다. 알림 배지는 사용자가 아직 닫지 않았거나 반응하지 않은 앱 관련 알림이 있는지 여부를 반영합니다. 알림 배지는 알림 도트라고도 불립니다. 알림 배지를 조정하는 방법에 대해 알아보려면 알림 배지 가이드를 참조하세요.
- 다시 알림: 사용자가 알림이 나중에 나타나도록 다시 알림을 설정할 수 있습니다. 알림이 다시 표시될 때는 처음과 같은 중요도로 표시됩니다. 앱은 다시 알림으로 설정된 알림을 제거하거나 업데이트할 수 있지만, 다시 알림으로 설정된 알림은 업데이트하면 다시 표시되지 않습니다.
- 알림 제한 시간: 이제 알림을 생성할 때
setTimeoutAfter()
을 사용하여 제한 시간을 설정할 수 있습니다. 이 메서드를 사용하여 일정 시간이 지나면 알림을 취소하도록 지정할 수 있습니다. 필요한 경우, 지정된 제한 시간이 지나기 전에 알림을 취소할 수 있습니다. - 알림 설정:
Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES
인텐트를 사용하여 앱 알림 설정의 링크를 만들 때 나타나는 텍스트를 설정하려면setSettingsText()
를 호출합니다. 설정을 필터링하기 위해 다음과 같은 인텐트 엑스트라를 시스템이 제공할 수도 있으며, 앱이 사용자에게 이러한 엑스트라를 표시해야 합니다:EXTRA_CHANNEL_ID
,NOTIFICATION_TAG
및NOTIFICATION_ID
. - 알림 닫기: 이제 시스템에서 사용자가 알림을 닫았는지 앱이 알림을 제거했는지 구분할 수 있습니다. 알림이 어떻게 닫혔는지 확인하려면
NotificationListenerService
클래스의 새onNotificationRemoved()
메서드를 구현해야 합니다. - 배경 색상: 알림의 배경 색상을 설정하고 활성화할 수 있습니다. 사용자가 한 눈에 볼 수 있도록 중요한 작업에 대한 알림에만 이 기능을 사용해야 합니다. 예를 들어, 운전 중 길찾기 또는 진행 중인 통화와 관련된 알림에 대해 배경 색상을 설정할 수 있습니다.
Notification.Builder.setColor()
를 사용하여 원하는 배경 색상을 설정할 수도 있습니다. 이때Notification.Builder.setColorized()
를 사용하면 알림에 배경 색상을 사용하는 기능을 활성화할 수 있습니다. - 메시징 스타일: 이제
MessagingStyle
클래스를 사용하는 알림이 접힌 형식으로 더 많은 내용을 표시합니다. 메시지와 관련된 알림에는MessagingStyle
클래스를 사용해야 합니다. 또한 새addHistoricMessage()
메서드를 사용하여 메시징 관련 알림에 기록 메시지를 추가함으로써 대화에 맥락을 제공할 수 있습니다.

그림 1. 사용자가 앱 런처 아이콘을 길게 눌러 Android 8.0에서 알림을 볼 수 있습니다.
Autofill Framework
계정 생성, 로그인 및 신용카드 트랜잭션은 시간이 걸리고 오류가 발생하기 쉽습니다. 사용자는 이런 반복적 작업을 요구하는 앱에 쉽게 불만을 느낄 수 있습니다.
Android 8.0는 Autofill Framework를 도입하여 로그인 및 신용카드 양식 등과 같은 양식을 더 쉽게 작성할 수 있도록 지원합니다. 사용자가 Autofill에 옵트인하면 기존 앱과 새로운 앱에서 Autofill Framework를 사용할 수 있습니다.
앱에서 프레임워크를 사용하는 방식을 최적화하기 위해 몇 가지 단계를 취할 수 있습니다. 자세한 정보는 Autofill Framework 개요를 참조하세요.
PIP 모드
Android 8.0에서는 PIP(picture-in-picture) 모드로 액티비티를 시작할 수 있습니다. PIP는 주로 동영상 재생에 사용되는 특수한 유형의 다중 창 모드입니다. PIP 모드는 이미 Android TV에서 제공되고 있으며 Android 8.0는 다른 Android 기기에서 이 기능을 제공합니다.
액티비티가 PIP 모드일 때는 일시 정지 상태이지만 계속 콘텐츠를 표시해야 합니다. 따라서 앱이 onPause()
핸들러에서 재생을 일시 중지하지 않도록 해야 합니다. 대신 onStop()
에서 동영상을 일시 중지했다가 onStart()
에서 계속 재생해야 합니다. 자세한 정보는 다중 창 수명 주기를 참조하세요.
액티비티가 PIP 모드를 사용할 수 있도록 지정하려면 매니페스트에서 android:supportsPictureInPicture
를 true로 설정합니다. (Android 8.0부터는 PIP 모드를 지원하려는 경우 Android TV나 다른 Android 기기에서 android:resizeableActivity
를 true로 설정할 필요가 없습니다. 액티비티가 다른 다중 창 모드를 지원할 때만 android:resizeableActivity
를 설정하면 됩니다.)
API 변경 사항
Android 8.0에는 PictureInPictureParams
라는 새로운 객체가 도입됩니다. 이 객체를 PIP 메서드에 전달하여 PIP 모드일 때 액티비티의 동작 방법을 지정할 수 있습니다. 이 객체는 액티비티의 기본 가로세로 비율 등과 같은 속성을 지정합니다.
PIP 추가에서 설명한 기존 PIP 모드를 이제 Android TV뿐만 아니라 모든 Android 기기에서 사용할 수 있습니다. 또한, Android 8.0는 PIP 모드를 지원하기 위해 다음 메서드를 제공합니다.
Activity.enterPictureInPictureMode(PictureInPictureParams args)
: PIP 모드에서 액티비티 위치를 지정합니다. 액티비티의 가로세로 비율 및 기타 구성 설정은 args를 통해 지정됩니다. args에서 어떤 필드가 비어 있을 경우, 시스템은 마지막으로Activity.setPictureInPictureParams()
를 호출했을 때 설정된 값을 사용합니다.지정된 액티비티는 화면 모서리에 배치되고 나머지 화면은 화면에 있던 이전 액티비티로 채워집니다. PIP 모드로 진입하는 액티비티는 일시 중지 상태가 되지만 시작된 상태로 유지됩니다. 사용자가 PIP 액티비티를 탭하면 시스템은 사용자가 상호작용하도록 메뉴를 표시합니다. PIP 상태일 때는 터치 이벤트가 액티비티에 도달하지 않습니다.
-
Activity.setPictureInPictureParams()
: 액티비티의 PIP 구성 설정을 업데이트합니다. 액티비티가 현재 PIP 모드에 있으면 설정이 업데이트됩니다. 이는 액티비티의 가로세로 비율이 변경될 때 유용합니다. 액티비티가 PIP 모드가 아닐 때는 호출한enterPictureInPictureMode()
메서드와 관계없이 이 구성 설정이 사용됩니다.
다운로드 가능한 글꼴
Android 8.0와 Android 지원 라이브러리 26을 사용하면, 글꼴을 APK에 번들링하거나 APK로 글꼴을 다운로드하는 대신 글꼴을 제공자 애플리케이션에게 요청할 수 있습니다. 이 기능은 APK 크기를 줄여주고, 앱 설치 성공률을 높여주며, 동일 글꼴을 여러 앱이 공유하도록 허용합니다.
글꼴 다운로드에 대한 자세한 정보는 다운로드 가능한 글꼴을 참조하세요.
XML의 글꼴
Android 8.0는 글꼴을 리소스로 사용할 수 있는 Fonts in XML이라는 새로운 기능을 도입합니다. 즉, 글꼴을 자산으로 번들할 필요가 없습니다. 글꼴은 R
파일로 컴파일되고 시스템에서 자동으로 리소스로 사용할 수 있습니다. 그런 다음 새로운 리소스 유형인 font
의 도움을 통해 해당 글꼴에 액세스할 수 있습니다.
지원 라이브러리 26은 API 버전 14 이상이 실행되는 기기에서 이 기능을 완벽하게 지원합니다.
글꼴을 리소스로 사용하고 시스템 글꼴을 검색하는 방법에 대한 자세한 정보는 XML의 글꼴을 참조하세요.
TextView 자동 크기 조절
Android 8.0에서는 TextView 크기에 따라 텍스트의 크기를 자동으로 늘리거나 줄일 수 있습니다. 다시 말해, 다양한 화면에서 또는 동적 콘텐츠로 텍스트 크기를 더 쉽게 최적화할 수 있습니다. Android 8.0의 TextView 자동 크기 조절에 대한 자세한 정보는 TextView 자동 크기 조절을 참조하세요.
어댑티브 아이콘
Android 8.0에는 어댑티브 런처 아이콘이 도입됩니다. 어댑티브 아이콘은 시각적 효과를 지원하며, 다른 기기 모델에서 다양한 모양을 표시할 수 있습니다. 어댑티브 아이콘을 만드는 방법에 대해 알아보려면 어댑티브 아이콘 미리보기 기능 가이드를 참조하세요.
색상 관리
이제 이미징 앱을 개발하는 Android 개발자가 폭넓은 색상 범위를 표시할 수 있는 새로운 기기를 이용할 수 있습니다. 폭넓은 색상 범위의 이미지를 표시하려면 앱이 자체 매니페스트에서 플래그를 활성화해야 하며(각 액티비티마다), 폭넓은 색상 프로필(AdobeRGB, Pro Photo RGB, DCI-P3 등)을 포함한 비트맵을 로드해야 합니다.
WebView API
Android 8.0에서는 웹 콘텐츠를 앱에 표시하는 WebView
객체를 관리할 수 있는 여러 API를 제공합니다. 이러한 API는 앱의 안정성과 보안을 개선해 주며 다음과 같은 API가 포함됩니다.
- Version API
- Google SafeBrowsing API
- Termination Handle API
- Renderer Importance API
이러한 API에 대해 자세히 알아보려면 WebViews 관리를 참조하세요.
바로가기 및 위젯 고정
Android 8.0는 단축키와 위젯의 인앱 고정 기능을 제공합니다. 앱에서 사용자 권한에 따라 이러한 지원되는 런처에 대해 고정된 단축키와 위젯을 생성할 수 있습니다.
자세한 정보는 단축키 및 위젯 고정 미리보기 기능 가이드를 참조하세요.
최대 화면 가로세로 비율
Android 7.1(API 레벨 25) 이하를 대상으로 하는 앱은 기본 최대 화면 가로세로 비율이 1.86입니다. Android 8.0 이상을 대상으로 하는 앱은 기본 최대 화면 가로세로 비율이 없습니다. 앱이 최대 화면 가로세로 비율을 설정할 필요가 있는 경우에는 액티비티를 정의하는 매니페스트 파일에서 maxAspectRatio 특성을 사용하세요.다중 디스플레이 지원
Android 8.0부터는 플랫폼에서 다중 디스플레이 지원이 강화됩니다. 액티비티가 다중 창 모드를 지원하고 다중 디스플레이 기기에서 실행될 경우, 사용자가 다른 디스플레이로 액티비티를 옮길 수 있습니다. 앱이 액티비티를 시작할 때 해당 액티비티를 실행할 디스플레이를 지정할 수 있습니다.
참고: 액티비티가 다중 창 모드를 지원하면 Android 8.0는 해당 액티비티에 대해 다중 디스플레이 지원을 자동으로 활성화합니다. 앱을 테스트하여 다중 디스플레이 환경에서 적절히 작동하는지 확인해야 합니다.
앱에 다중 디스플레이가 있더라도 다시 실행되는 상태에서는 한 번에 한 액티비티만 실행할 수 있습니다. 포커스가 있는 액티비티가 다시 시작된 상태가 되고, 다른 모든 보이는 액티비티가 일시 정지되지만 중단되지는 않습니다. 여러 액티비티가 보이는 경우 액티비티 수명 주기에 대한 자세한 정보는 다중 창 수명 주기를 참조하세요.
사용자가 다른 디스플레이로 액티비티를 옮기면 시스템이 액티비티 크기를 조정하고 필요에 따라 런타임 변경을 수행합니다. 액티비티 스스로 구성 변경을 처리하거나, 시스템이 액티비티가 포함된 프로세스를 소멸시키고 새 크기로 액티비티를 다시 생성하게 할 수 있습니다. 자세한 정보는 구성 변경 사항 처리를 참조하세요.
ActivityOptions
는 다중 디스플레이를 지원하는 두 개의 새로운 메서드를 제공합니다.
setLaunchDisplayId()
- 액티비티가 시작되면 어느 디스플레이가 액티비티를 표시해야 하는지 지정합니다.
getLaunchDisplayId()
- 액티비티의 현재 실행 디스플레이를 반환합니다.
adb 셸이 다중 디스플레이를 지원하도록 확장되었습니다. shell start
명령을 사용하여 액티비티를 시작하고 액티비티의 대상 디스플레이를 지정할 수 있습니다.
adb shell start <activity_name> --display <display_id>
통합된 레이아웃 여백 및 패딩
Android 8.0를 사용하면 View
요소의 반대쪽에서 같은 여백 또는 안쪽 여백을 사용하는 상황을 더 쉽게 지정할 수 있습니다. 특히, 이제는 레이아웃 XML 파일에 다음 속성을 사용할 수 있습니다.
-
layout_marginTop
과layout_marginBottom
을 동시에 정의하는layout_marginVertical
-
layout_marginLeft
와layout_marginRight
를 동시에 정의하는layout_marginHorizontal
-
paddingTop
과paddingBottom
을 동시에 정의하는paddingVertical
-
paddingLeft
와paddingRight
를 동시에 정의하는paddingHorizontal
참고: 텍스트 방향을 포함한 다양한 언어 및 문화를 지원하는 앱의 로직을 사용자설정하는 경우, 이러한 속성이 layout_marginStart
, layout_marginEnd
, paddingStart
또는 paddingEnd
의 값에 영향을 주지 않는다는 점에 유의하세요. 새로운 수직 및 수평 레이아웃 속성 외에, 이러한 값을 직접 설정하여 텍스트 방향에 따라 달라지는 레이아웃 동작을 만들 수 있습니다.
포인터 캡처
게임, 원격 데스크톱, 가상화 클라이언트 등의 몇몇 앱은 마우스 포인터에 대한 제어권 획득을 통해 큰 이점을 누릴 수 있습니다. 포인터 캡처는 앱에서 포커스된 뷰로 모든 마우스 이벤트를 전달하는 방식으로 이러한 제어 권한을 제공하는 Android 8.0의 새로운 기능입니다.
Android 8.0에서부터, 앱의 View
는 포인터 캡처를 요청하고 캡처된 포인터 이벤트를 처리하는 리스너를 정의할 수 있습니다. 이 모드에서는 마우스 포인터가 숨겨집니다. 뷰는 더 이상 마우스 정보가 필요하지 않을 경우 포인터 캡처를 해제할 수 있습니다. 시스템도 예컨대 사용자가 다른 앱을 열 때와 같이, 뷰가 포커스를 잃을 경우 포인터 캡처를 해제할 수 있습니다.
앱에서 이 기능을 사용하는 자세한 방법은 포인터 캡처를 참조하세요.
앱 범주
Android 8.0에서는 관련된 적절한 범주를 각 앱이 선언할 수 있습니다. 이들 범주는 용도나 기능이 유사한 앱을 모아서 사용자에게 표시할 때 사용됩니다(예: 데이터 사용량, 배터리 사용량 또는 저장소 사용량). 앱의 범주를 정의하기 위해 android:appCategory
특성을 <application>
매니페스트 태그에 설정할 수 있습니다.
Android TV 런처
Android 8.0는 Android 8.0용 Android TV 에뮬레이터 및 Nexus Player 기기 이미지와 함께 사용 가능한, 새로운 콘텐츠 중심의 Android TV 홈 화면 환경을 포함합니다. 새로운 홈 화면은 채널에 해당하는 행의 동영상 콘텐츠를 구성하며, 시스템의 앱이 각 채널을 프로그램으로 채웁니다. 앱은 여러 채널을 게시할 수 있고, 사용자는 홈 화면에서 보고 싶은 채널을 구성할 수 있습니다. Android TV 홈 화면은 사용자의 시청 습관을 바탕으로 앱에서 제공하는 프로그램으로 채워지는 Watch Next 행도 포함합니다. 또한, 앱은 사용자가 프로그램에 포커스를 맞출 때 자동으로 재생되는 동영상 미리보기도 제공할 수 있습니다. 채널과 프로그램을 채우기 위한 API는 Android 8.0와 함께 Android 지원 라이브러리 모듈로 배포되는 TvProvider API의 일부입니다.
AnimatorSet
Android 8.0부터는 AnimatorSet
API에서 탐색과 역방향 재생을 지원합니다. 탐색을 통해 애니메이션 세트의 위치를 특정 시점으로 설정할 수 있습니다. 앱에 실행 취소할 수 있는 애니메이션이 포함된 경우 역방향 재생이 유용합니다. 2개의 애니메이션 세트를 별도로 정의하는 대신 같은 애니메이션을 역방향으로 재생할 수 있습니다.
입력 및 탐색
키보드 탐색 클러스터
그림 2처럼 앱의 액티비티가 복잡한 뷰 계층 구조를 사용하는 경우, UI 요소 그룹을 클러스터로 구성하면 키보드 탐색이 더 쉬워집니다. 사용자가 Meta+Tab 또는 Search+Tab(Chromebook 기기) 키를 눌러 클러스터 간에 이동할 수 있습니다. 클러스터의 적절한 예로는 측면 패널, 탐색 메뉴, 기본 콘텐츠 영역 그리고 많은 하위 요소들을 포함할 수 있는 요소를 들 수 있습니다.

View
또는 ViewGroup
요소를 클러스터로 만들려면, 요소의 레이아웃 XML 파일에서 android:keyboardNavigationCluster
특성을 true
로 설정하거나, 앱의 UI 로직에서 true
를 setKeyboardNavigationCluster()
로 전달합니다.
참고: 클러스터는 중첩될 수 없지만, 서로 다른 레벨의 계층 구조에서 비중첩 클러스터가 나타날 수도 있습니다. 클러스터를 중첩시키려고 시도하면 프레임워크는 최상위 ViewGroup
요소만을 클러스터로 간주합니다.
터치스크린이 있는 기기에서는, 클러스터 지정 ViewGroup
객체의 android:touchscreenBlocksFocus
요소를 true
로 설정할 수 있으며 이 경우 해당 클러스터에 대해 클러스터 전용 탐색이 허용됩니다. 이 구성을 클러스터에 적용하면, 사용자가 Tab 키나 화살표 키를 사용하여 클러스터를 탐색할 수 없으며, 그 대신 클러스터 탐색 키보드 조합을 눌러야 합니다.
기본 포커스 보기
Android 8.0에서는 생성되거나 재생성된 액티비티가 다시 시작되고 사용자가 키보드 탐색 키(예: 탭 키)를 누른 후에 포커스를 받아야 하는 View
를 할당할 수 있습니다. 이 "기본 포커스" 설정을 적용하려면, UI 요소가 포함된 레이아웃 XML 파일에서 View
요소의 android:focusedByDefault
특성을 true
로 설정하거나, 앱의 UI 로직에서 true
를 setFocusedByDefault()
로 전달합니다.
시스템
새로운 StrictMode 탐지기
Android 8.0에서는 앱의 잠재적 버그를 찾도록 도와주는 세 개의 새로운 StrictMode 탐지기를 추가합니다.
detectUnbufferedIo()
는 앱이 버퍼링없이 데이터를 읽거나 쓰는 경우 이를 탐지하며, 성능에 상당한 영향을 미칩니다.detectContentUriWithoutPermission()
은 앱 외부에서 액티비티를 시작할 때 이 앱이 실수로 또 다른 앱에 권한을 부여하는 것을 잊어버린 경우 이를 탐지합니다.detectUntaggedSockets()
는 앱이 디버깅 용도로setThreadStatsTag(int)
를 사용하지 않고 네트워크 트래픽을 수행하는 경우 이를 탐지합니다.
캐시된 데이터
Android 8.0는 캐시된 데이터에 대한 더 나은 지침과 동작을 제공합니다. 이제 각 앱에는 캐시된 데이터를 위한 디스크 공간 할당량이 부여됩니다. 이 할당량은 getCacheQuotaBytes(UUID)
에 의해 반환됩니다.
시스템이 디스크 공간을 늘려야 하는 경우, 지정된 할당량을 초과하는 캐시 파일을 앱에서 먼저 삭제합니다. 따라서 지정된 할당량 아래로 캐시된 데이터를 유지한다면, 필요한 경우 해당 캐시 파일이 시스템에서 마지막으로 지워집니다. 앱에서 어떤 캐시 파일을 삭제할지 결정할 때 시스템은 가장 오래된 파일을 먼저 삭제할 것을 고려합니다(수정된 시간으로 판별).
또한 시스템이 캐시된 데이터를 비우는 방식을 디렉토리별로 제어할 수 있는 두 가지 새로운 동작이 있습니다.
StorageManager.setCacheBehaviorAtomic()
은 디렉토리와 그 안의 모든 콘텐츠가 하나의 최소 단위로 삭제되어야 함을 나타냅니다.setCacheBehaviorTombstone(File, boolean)
은 디렉토리 내의 파일을 삭제하는 대신, 파일을 0바이트 길이로 자르고 빈 파일은 그대로 두어야 함을 나타냅니다.
마지막으로, 대용량 파일에 디스크 공간을 할당할 경우, 새로운 allocateBytes(FileDescriptor, long)
API 사용을 고려하세요. 이 API는 여러분의 요청을 충족시키기 위해 (필요에 따라) 다른 앱에 속하는 캐시 파일을 자동으로 지웁니다. 새로운 데이터를 저장할 기기의 디스크 공간이 충분한지 여부를 결정할 때, getUsableSpace()
를 사용하는 대신 getAllocatableBytes(UUID)
를 호출하세요. 왜냐하면 이 메서드는 시스템이 자동으로 지우는 모든 캐시된 데이터를 고려하기 때문입니다.
콘텐츠 제공자 페이징
한 번에 한 페이지에 대량의 데이터 집합을 로드하는 기능을 지원하도록 콘텐츠 제공자를 업데이트했습니다. 예를 들어, 수천 개의 이미지가 포함된 사진 앱은 데이터의 하위 집합을 쿼리하여 페이지에 표시할 수 있습니다. 콘텐츠 제공자가 반환한 각 결과 페이지는 단일 Cursor 객체로 표시됩니다. 페이징 기능을 사용하려면 클라이언트와 제공자가 모두 이 기능을 구현해야 합니다.
콘텐츠 제공자의 변경 사항에 대한 자세한 정보는 ContentProvider
및 ContentProviderClient
를 참조하세요.
콘텐츠 새로고침 요청
이제 ContentProvider
및 ContentResolver
클래스에는 refresh()
메서드가 포함되므로, 요청한 정보가 최신 정보인지를 클라이언트가 쉽게 알 수 있습니다.
ContentProvider
를 확장하여 맞춤 콘텐츠 새로고침 로직을 추가할 수 있습니다. true
를 반환하도록 refresh()
메서드를 재정의했는지 확인하세요. 그러면 여러분이 직접 데이터 새로고침을 시도했음을 제공자 클라이언트에게 알릴 수 있습니다.
클라이언트 앱은 refresh()
라고도 불리는 다른 메서드를 호출하여 새로 고쳐진 콘텐츠를 명시적으로 요청할 수 있습니다. 이 메서드를 호출할 때, 새로고침을 수행할 데이터의 URI를 전달합니다.
참고: 네트워크를 통해 데이터를 요청할 경우도 있으므로, 콘텐츠가 오래되었다는 확신이 드는 경우에만 클라이언트측에서 refresh()
를 호출해야 합니다. 이러한 형태의 콘텐츠 새로고침을 수행하는 가장 일반적인 이유는 스와이프하여 새로고침 동작에 응답하는 경우입니다. 이 동작은 현재 UI에 최신 콘텐츠를 표시하도록 명시적으로 요청합니다.
JobScheduler 개선 사항
Android 8.0에서는 JobScheduler
에 대해 많은 개선 사항이 도입됩니다. 일반적으로 예약된 작업을 사용하여 현재 제한되어 있는 백그라운드 서비스나 암시적 브로드캐스트 수신기를 대체할 수 있으므로, 이러한 개선 사항 덕분에 앱이 더 쉽게 새로운 백그라운드 실행 제한을 준수할 수 있습니다.
JobScheduler
에 대한 업데이트에는 다음 사항이 포함됩니다.
-
이제 작업 큐를 예약된 작업과 연결할 수 있습니다. 작업의 큐에 작업 항목을 추가하려면
JobScheduler.enqueue()
를 호출합니다. 작업이 실행 중일 때는 보류 중인 작업을 큐에서 제거하고 실행 중인 작업을 처리할 수 있습니다. 이 기능은 이전에는 백그라운드 서비스를 시작하기 위해 호출했던 다수의 사용 사례, 특히IntentService
를 구현하는 서비스를 처리합니다. -
이제
JobInfo.Builder.setClipData()
를 호출하여ClipData
를 작업과 연결할 수 있습니다. 이 옵션을 사용하면 URI 권한을Context.startService()
로 전달할 수 있는 방법과 유사하게 이런 권한 허용을 작업과 연결할 수 있습니다. 작업 큐에서 인텐트와 함께 URI 권한 부여를 사용할 수도 있습니다. -
예약된 작업은 이제 다음과 같은 여러 가지 새로운 제약 조건을 지원합니다.
JobInfo.isRequireStorageNotLow()
- 기기의 사용 가능 저장용량이 부족하면 작업이 실행되지 않습니다.
JobInfo.isRequireBatteryNotLow()
- 배터리 잔량이 임계 수준이거나 그보다 낮으면 작업이 실행되지 않는데, 임계 수준에 이르면 기기에 Low battery warning 시스템 대화상자가 표시됩니다.
NETWORK_TYPE_METERED
- 대부분의 모바일 데이터 요금제와 같이, 작업을 위해 데이터 통신 네트워크 연결이 필요합니다.
사용자설정 데이터 스토어
Android 8.0에서 자신의 기본 설정에 맞게 데이터 스토어를 사용자설정할 수 있습니다. 이는 여러분의 앱이 기본 설정을 클라우드나 로컬 데이터베이스에 저장하는 경우나 기본 설정이 기기별로 다른 경우에 유용할 수 있습니다. 데이터 스토어 구현에 대한 자세한 정보는 사용자설정 데이터 스토어를 참조하세요.
findViewById() 서명 변경
이제 findViewById()
메서드의 모든 인스턴스는 View
대신
<T extends View> T
를 반환합니다. 이 변경은 다음과 같은 의미를 지닙니다.
- 기존 코드에 모호한 반환 유형이 있을 수 있습니다(예:
someMethod(View)
및someMethod(TextView)
가 둘 다findViewById()
호출 결과를 취하는 경우). - Java 8 소스 언어를 사용하는 경우, 반환 유형이 제한되지 않는다면
View
에 대한 명시적 형변환이 필요합니다(예:assertNotNull(findViewById(...)).someViewMethod())
). - final이 아닌
findViewById()
메서드(예:Activity.findViewById()
)를 재정의하는 경우 그 반환 유형을 업데이트해야 합니다.
미디어 개선
VolumeShaper
새로운 VolumeShaper 클래스가 있습니다. 이 클래스를 사용하여 페이드 인, 페이드 아웃, 크로스 페이드 등의 짧은 자동 볼륨 전환을 수행할 수 있습니다.
오디오 포커스 개선
오디오 앱은 오디오 포커스를 요청하고 중단하는 방식으로 기기에서 오디오 출력을 공유합니다. 앱은 재생을 시작 또는 중지하거나 볼륨을 더킹하는 방식으로 포커스의 변화를 처리합니다. 새로운 AudioFocusRequest
클래스가 있습니다. 이 클래스와 함께, 앱에서 오디오 포커스의 변화를 처리할 때 사용하는 새로운 기능으로 자동 더킹과 지연된 포커스 게인이 있습니다.
미디어 지표
새로운 getMetrics()
메서드는 특성과 값의 맵으로 표시되는 구성 및 성능 정보를 포함한 PersistableBundle
객체를 반환합니다. getMetrics()
메서드는 다음과 같은 미디어 클래스에 대해 정의됩니다.
MediaPlayer.getMetrics()
MediaRecorder.getMetrics()
MediaCodec.getMetrics()
MediaExtractor.getMetrics()
지표는 각 인스턴스에 대해 개별적으로 수집되며 인스턴스 수명 동안 지속됩니다. 사용할 수 있는 지표가 없으면 메서드는 null을 반환합니다. 반환되는 실제 지표는 클래스에 따라 달라집니다.
MediaPlayer
Android 8.0에서는 MediaPlayer 클래스에 여러 새로운 메서드를 추가합니다. 이들 메서드는 앱의 미디어 재생 처리를 여러 가지 방식으로 개선할 수 있습니다.
이제 MediaPlayer는 샘플 수준 암호화를 지원합니다.
MediaRecorder
- 이제 MediaRecorder는 스트리밍에 유용한 MPEG2_TS 형식을 지원합니다.
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS);
MediaRecorder.OutputFormat
를 참조하세요. - 이제
MediaMuxer
는 개수에 제한없이 오디오와 동영상 스트림을 처리할 수 있습니다. 더 이상 하나의 오디오 트랙이나 하나의 동영상 트랙으로 제한되지 않습니다.addTrack()
을 사용하여 원하는 갯수만큼 트랙을 믹싱하세요. - 또한
MediaMuxer
는 사용자가 정의한 프레임당 정보를 포함하는 하나 이상의 메타데이터 트랙을 추가할 수 있습니다. 메타데이터의 형식은 애플리케이션에 의해 정의됩니다. 메타데이터 트랙은 MP4 컨테이너에만 지원됩니다.
메타데이터는 오프라인 처리에 유용할 수 있습니다. 예를 들어, 센서의 자이로 신호는 동영상을 안정화하는 데 사용될 수 있습니다.
메타데이터 트랙을 추가할 때 트랙의 mime 형식은 "application/" 접두사로 시작해야 합니다. 메타데이터 쓰기는 동영상/오디오 데이터 쓰기와 동일하며, 단 데이터가 MediaCodec
으로부터 오지는 않습니다. 그 대신, 앱은 연관된 타임스탬프가 있는 ByteBuffer
를 writeSampleData()
메서드에 전달합니다. 타임스탬프는 동영상 및 오디오 트랙과 시간 베이스가 동일해야 합니다.
생성된 MP4 파일은 메타데이터의 mime 형식 시그널링을 위해 ISOBMFF의 섹션 12.3.3.2에 정의된 TextMetaDataSampleEntry
를 사용합니다. 메타데이터 트랙이 있는 파일을 추출할 때 MediaExtractor
를 사용할 경우, 이 메타데이터의 mime 형식은 MediaFormat
으로 추출됩니다.
오디오 재생 컨트롤
Android 8.0를 사용하면 기기의 사운드 생성 방식을 쿼리하고 요청할 수 있습니다. 오디오 재생에 대해 다음과 같은 방식으로 제어할 수 있으므로 서비스가 유리한 기기 조건 하에서만 더 쉽게 사운드를 생성할 수 있습니다.
Google 어시스턴트를 위한 새로운 오디오 사용 유형
AudioAttributes
클래스는 새로운 사운드 형식인 USAGE_ASSISTANT
를 포함하며, 이는 Google 어시스턴트가 기기에서 말하는 대답에 해당합니다.
기기 오디오 재생에 대한 변경 사항
개발자의 서비스에서 특정 기기 오디오 구성이 활성 상태일 때만 사운드 생성을 시작하도록 하고 싶은 경우, AudioManager
클래스를 사용하여 AudioManager.AudioPlaybackCallback
의 인스턴스를 등록할 수 있으며, 여기에서 onPlaybackConfigChanged()
메서드는 현재 활성화된 오디오 속성 세트를 식별하는 데 도움이 됩니다.
오디오 포커스에 대한 명시적 요청
서비스는 requestAudioFocus()
메서드를 사용하여 기기 전체에 적용되는 오디오 포커스를 수신하기 위해 더욱 세분화된 요청을 제출할 수 있습니다. AudioFocusRequest.Builder
를 사용하여 만드는 AudioFocusRequest
객체를 전달합니다. 이 빌더 클래스에서 다음 옵션을 지정할 수 있습니다.
AUDIOFOCUS_GAIN_TRANSIENT
또는AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
과 같이 원하는 포커스의 유형.- 다른 오디오 서비스가 기기 포커스를 인계받을 때 서비스가 더욱 은밀하게 계속되어야 할지 또는 완전히 일시 중지되어야 할지 여부.
- 기기가 준비될 때까지 서비스가 포커스를 얻을 때까지 대기할 수 있는지 여부.
참고: AudioFocusRequest
의 인스턴스를 빌드할 때, 서비스가 setAcceptsDelayedFocusGain()
을 호출하여 사운드를 생성할 때까지 대기할 수 있음을 나타내는 경우, 서비스가 사운드 생성을 시작할 수 있는 시점을 인식하도록 setOnAudioFocusChangeListener()
도 호출해야 합니다.
개선된 미디어 파일 액세스
저장소 액세스 프레임워크(SAF)를 사용하면 앱이 사용자설정 DocumentsProvider
를 노출하여 다른 앱에 데이터 소스의 파일에 대한 액세스를 제공할 수 있습니다. 실제로, 문서 제공자는 네트워크 저장소에 있는 파일이나 MTP(Media Transfer Protocol)같은 프로토콜을 사용하는 파일에 대한 액세스도 제공할 수 있습니다.
그러나 대용량 미디어 파일을 원격 데이터 소스에서 액세스하는 경우 약간의 문제가 발생합니다.
- 미디어 플레이어는 문서 제공자의 파일에 대해 검색 가능한 액세스를 요구합니다. 대용량 미디어 파일이 원격 데이터 소스에 있는 경우, 문서 제공자는 모든 데이터를 미리 가져와서 스냅샷 파일 설명자를 생성해야 합니다. 미디어 플레이어는 파일 설명자가 없는 파일은 재생할 수 없으므로, 문서 제공자가 파일 다운로드를 마칠 때까지는 재생을 시작할 수 없습니다.
- 포토 앱과 같은 미디어 수집 관리자는 범위가 지정된 폴더를 통해 외부 SD 카드에 저장되어 있는 미디어에 연결하기 위해 일련의 액세스 URI를 거쳐야 합니다. 이런 액세스 패턴은 미디어에서 대량으로 이루어지는 이동, 복사, 삭제 등의 작업 속도를 현저히 떨어뜨립니다.
- 미디어 수집 관리자는 URI가 주어진 문서의 위치를 결정할 수 없습니다. 따라서 이러한 유형의 앱에서는 사용자가 미디어 파일을 저장하는 위치를 선택하기 어렵게 만듭니다.
Android 8.0는 저장소 액세스 프레임워크를 개선하여 이런 문제를 해결합니다.
사용자설정 문서 제공자
Android 8.0부터는, 저장소 액세스 프레임워크(SAF)를 통해 사용자설정 문서 제공자가 원격 데이터 소스의 파일에 대해 검색 가능한 파일 설명자를 생성할 수 있습니다. SAF는 파일을 열어 기본 검색 가능한 파일 설명자를 가져올 수 있습니다. 그런 다음 불연속적인 바이트 요청을 문서 제공자에게 전달합니다. 이 기능을 통해 문서 제공자는 전체 파일을 미리 캐싱하는 대신 미디어 플레이어 앱이 요청했던 정확한 바이트 범위를 반환할 수 있습니다.
이 기능을 사용하려면 새로운 StorageManager.openProxyFileDescriptor()
메서드를 호출해야 합니다. openProxyFileDescriptor()
메서드는 ProxyFileDescriptorCallback
객체를 콜백으로 받습니다. SAF는 문서 제공자로부터 반환된 파일 설명자에 대해 클라이언트 애플리케이션이 파일 작업을 수행할 때마다 콜백을 호출합니다.
직접 문서 액세스
Android 8.0에서는 getDocumentUri()
메서드를 사용하여 주어진 mediaUri
와 동일한 문서를 참조하는 URI를 얻을 수 있습니다. 하지만 반환되는 URI는 DocumentsProvider
의 지원을 받으므로 미디어 수집 관리자가 범위가 지정된 디렉토리의 트리를 거칠 필요 없이 문서에 직접 액세스할 수 있습니다. 결과적으로, 미디어 관리자는 문서에서 파일 작업을 훨씬 더 빠르게 수행할 수 있습니다.
주의: getDocumentUri()
메서드는 미디어 파일을 찾기만 할 뿐, 이런 파일에 액세스할 권한을 앱에 부여하지 않습니다. 미디어 파일에 대한 액세스 권한을 얻는 방법을 자세히 알아보려면 참조 문서를 참조하세요.
문서의 경로
Android 8.0에서 저장소 액세스 프레임워크를 사용할 때 DocumentsContract
및 DocumentsProvider
클래스에서 모두 사용 가능한 findDocumentPath()
메서드를 사용하여 문서의 ID가 지정된 파일 시스템의 루트에서 경로를 확인할 수 있습니다. 이 메서드는 DocumentsContract.Path
객체에서 이 경로를 반환합니다. 파일 시스템에서 같은 문서에 대해 정의된 경로가 여러 개 있는 경우, 이 메서드는 지정된 ID를 가진 문서에 연결하기 위해 가장 자주 사용되는 경로를 반환합니다.
이 기능은 다음과 같은 상황에서 특히 유용합니다.
- 개발자의 앱은 특정 문서의 위치를 표시하는 'save as' 대화상자를 사용합니다.
- 앱은 검색 결과 뷰에 폴더를 표시하며, 사용자가 특정 폴더를 선택하는 경우 앱이 그 폴더 내에 있는 하위 문서를 로드해야 합니다.
참고: 앱이 경로에 있는 문서 중 일부에만 액세스할 권한이 있는 경우, findDocumentPath()
의 반환 값은 앱이 액세스할 수 있는 폴더와 문서만 포함합니다.
연결
Wi-Fi Aware
Android 8.0에서는 Wi-Fi Aware 지원이 추가되며 이 기능은 NAN(Neighbor Awareness Networking) 사양을 기반으로 합니다. 적절한 Wi-Fi Aware 하드웨어가 기기에 있다면, 앱과 인접 기기들이 인터넷 액세스 지점 없이도 Wi-Fi를 통해 검색과 통신을 수행할 수 있습니다. 저희는 하드웨어 파트너들과의 협력을 통해 최대한 신속하게 Wi-Fi Aware 기술을 기기에 제공할 것입니다. Wi-Fi Aware를 앱에 통합하는 방법에 대한 자세한 정보는 Wi-Fi Aware를 참조하세요.
블루투스
Android 8.0에서는 다음과 같은 기능을 추가하여 플랫폼의 블루투스 지원을 강화합니다.
- 곡-라이브러리 탐색이 가능한 AVRCP 1.4 표준 지원.
- BLE(Bluetooth Low-Energy) 5.0 표준 지원.
- Sony LDAC 코덱을 블루투스 스택에 통합.
부속 기기 페어링
Android 8.0는 블루투스, BLE, Wi-Fi를 통해 부속 기기와 페어링을 시도할 때 페어링 요청 대화상자를 맞춤설정할 수 있는 API를 제공합니다. 자세한 정보는 부속 기기 페어링을 참조하세요.
Android에서 블루투스 사용에 대한 자세한 정보는 블루투스 가이드를 참조하세요. Android 8.0에만 해당하는 블루투스 변경 사항에 대해서는 Android 8.0 동작 변경 사항 페이지의 블루투스 섹션을 참조하세요.
공유
스마트 공유
Android 8.0는 사용자의 맞춤설정된 공유 기본 설정에 대한 정보를 획득하여 공유할 앱의 각 콘텐츠 유형에 대해 더 정확히 파악합니다. 예를 들어, 사용자가 영수증 사진을 찍으면 Android 8.0가 지출 추적 앱을 추천할 수 있고, 사용자가 셀카를 찍으면 소셜 미디어 앱이 이미지를 더욱 효과적으로 처리할 수 있습니다. Android 8.0는 사용자의 맞춤설정된 기본 설정에 따라 이런 패턴을 전부 자동으로 학습합니다.
스마트 공유는 audio
, video
, text
, URL
등과 같이, image
이외의 콘텐츠 유형에 효과가 있습니다.
스마트 공유를 사용하려면 콘텐츠를 공유하는 인텐트에 최대 3개의 문자열 주석으로 구성된 ArrayList
를 추가합니다. 주석은 콘텐츠의 주요 구성 요소나 항목을 설명하는 내용이어야 합니다. 다음 코드 예시는 인텐트에 주석을 추가하는 방법을 보여줍니다.
ArrayList<String> annotations = new ArrayList<>(); annotations.add("topic1"); annotations.add("topic2"); annotations.add("topic3"); intent.putStringArrayListExtra( Intent.EXTRA_CONTENT_ANNOTATIONS, annotations );
스마트 공유 주석에 대한 자세한 내용은 EXTRA_CONTENT_ANNOTATIONS
를 참조하세요.
스마트 텍스트 선택
호환 기기에서, Android 8.0는 사용자가 더욱 의미 있는 방식으로 텍스트와 상호 작용하는 데 도움이 되는 앱을 사용합니다. 사용자가 엔터티(예를 들어, 주소 또는 식당 이름 같이 인식된 형식)에서 한 단어를 길게 누르면 시스템이 전체 엔터티를 선택합니다. 사용자가 선택한 텍스트 엔터티를 처리할 수 있는 앱을 포함할 수 있는 부동 툴바가 표시됩니다. 예를 들어, 시스템이 주소를 인식하는 경우 사용자를 지도 앱으로 안내할 수 있습니다.
시스템이 인식하는 엔터티에는 주소, URL, 전화 번호, 이메일 주소 등이 포함됩니다. 자세한 정보는 TextClassifier
를 참조하세요.
접근성
Android 8.0에서는 자체적인 접근성 서비스를 원하는 개발자를 위해 다음과 같은 접근성 기능을 지원합니다. 앱의 접근성을 더 높이는 방법에 대해 알아보려면 접근성을 참조하세요.
접근성 버튼
이제 접근성 서비스에서 접근성 버튼이 시스템 탐색 영역 내에 나타나도록 요청할 수 있습니다. 이 버튼을 통해 사용자는 언제 어디서나 자신의 기기에서 서비스의 기능을 신속하게 활성화할 수 있습니다. 그렇게 하려면 FLAG_REQUEST_ACCESSIBILITY_BUTTON
플래그를 AccessibilityServiceInfo
객체의 android:accessibilityFlags
특성에 추가합니다. 그런 다음, registerAccessibilityButtonCallback()
을 사용하여 콜백을 등록할 수 있습니다.
참고: 이 기능은 소프트웨어 렌더링 탐색 영역을 제공하는 기기에서만 사용이 가능합니다. 항상 isAccessibilityButtonAvailable()
을 사용하고 onAvailabilityChanged()
를 구현하여 접근성 버튼의 가용 여부에 따라 변경 사항에 응답합니다. 이런 방식의 경우, 접근성 버튼이 지원되지 않거나 사용할 수 없게 되더라도 사용자가 항상 서비스 기능에 액세스할 수 있습니다.
독립적인 볼륨 조절
Android 8.0에서는 STREAM_ACCESSIBILITY
볼륨 범주를 도입합니다. 이 범주를 사용하면 기기의 다른 사운드에 상관없이 접근성 서비스의 오디오 출력을 독립적으로 제어할 수 있습니다.
이 새로운 스트림 유형을 사용하여 접근성 볼륨을 제어하려면, 접근성 서비스 내의 FLAG_ENABLE_ACCESSIBILITY_VOLUME
옵션을 설정합니다. 그런 다음, adjustStreamVolume()
을 사용하여 기기의 접근성 오디오 볼륨을 변경할 수 있습니다.
지문 동작
접근성 서비스는 또한 기기의 지문 센서와 함께 대체 입력 메커니즘인 방향 스와이프(위, 아래, 왼쪽, 오른쪽)에 반응할 수도 있습니다. 이러한 상호작용에 대한 콜백을 수신하려면 아래의 단계를 순서대로 완료하세요.
USE_FINGERPRINT
권한과CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES
기능을 선언합니다.android:accessibilityFlags
특성 내에FLAG_REQUEST_FINGERPRINT_GESTURES
플래그를 설정합니다.registerFingerprintGestureCallback()
을 사용하여 콜백을 등록합니다.
모든 기기에 지문 센서가 포함된 것은 아님을 명심하세요. 기기가 센서를 지원하는지 여부를 알려면 isHardwareDetected()
메서드를 사용하세요. 지문 센서가 포함된 기기라도, 인증 용도로 사용 중이 아닐 때만 서비스에서 이 센서를 사용할 수 있습니다. 센서의 가용 시기를 알려면 isGestureDetectionAvailable()
메서드를 호출하고 onGestureDetectionAvailabilityChanged()
콜백을 구현하세요.
단어 수준 강조표시
TextView
객체에서 보이는 문자의 위치를 판별하기 위해, EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY
를 첫 번째 인수로 refreshWithExtraData()
에 전달할 수 있습니다. Bundle
객체는 두 번째 인수로 refreshWithExtraData()
에 제공되며, 이 객체를 업데이트하여 Rect
객체의 parcelable 배열을 포함시킬 수 있습니다. 각 Rect
객체는 특정 문자의 경계 상자를 나타냅니다.
화면상에 나타나는 콘텐츠를 구술하기 위해 서비스가 TextToSpeech
객체를 사용하면, 합성된 개별 단어를 TTS(텍스트 음성 변환) 엔진이 말하기 시작하는 타이밍에 대한 더욱 정밀한 정보를 얻을 수 있습니다(단, 이 경우 TTS 엔진이 이 정보를 제공해야 합니다). 이 엔진이 특정 텍스트 범위에 대한 오디오를 재생하기 시작하면, 텍스트 음성 변환 API는 onRangeStart()
메서드를 사용하여 해당 텍스트 범위의 음성 재생이 시작됨을 여러분의 서비스에게 알려줍니다.
자체 TextToSpeechService
구현을 만드는 경우, rangeStart()
메서드를 사용하여 이 새로운 기능을 지원할 수 있습니다.
표준화된 단방향 범위 값
AccessibilityNodeInfo
의 일부 인스턴스는 UI 요소에 값 범위가 있음을 나타내기 위해 AccessibilityNodeInfo.RangeInfo
의 인스턴스를 사용합니다. RangeInfo.obtain()
을 사용하여 어떤 범위를 생성할 때나 getMin()
및 getMax()
를 사용하여 범위의 극단값을 검색할 때 유의할 점은, 다음과 같이 Android 8.0에는 표준화된 단방향 범위 값이 정의되어 있다는 것입니다.
- 최소가 없는 범위의 경우,
Float.NEGATIVE_INFINITY
는 최소값을 나타냅니다. - 최대가 없는 범위의 경우,
Float.POSITIVE_INFINITY
는 최대값을 나타냅니다.
힌트 텍스트
Android 8.0에는 텍스트 편집 가능 객체의 힌트 텍스트와 상호 작용하기 위한 다음과 같은 여러 메서드가 있습니다.
isShowingHintText()
및setShowingHintText()
메서드는 각각 노드의 현재 텍스트 콘텐츠가 노드의 힌트 텍스트를 표시하는지 여부를 나타내고 설정합니다. 노드에 편집 가능 텍스트가 포함되지 않은 경우 절대로 힌트 텍스트를 포함해서는 안됩니다.- 힌트 텍스트 자체에 액세스하려면
getHintText()
를 사용하세요. 현재 객체에 힌트 텍스트가 표시되지 않더라도,getHintText()
에 대한 호출은 성공합니다.
연속 동작 디스패치
이제 GestureDescription.StrokeDescription
생성자에서 최종 인수인 willContinue
를 사용하여 여러분의 서비스에서 동일 프로그래밍 동작에 속하는 일련의 스트로크를 지정할 수 있습니다.
보안 및 개인정보 보호
권한
Android 8.0에서는 다음과 같이 전화통신과 관련된 여러 새로운 권한을 도입합니다.
-
ANSWER_PHONE_CALLS
권한을 사용하여 앱이 프로그래밍 방식으로 수신 통화에 응답하도록 할 수 있습니다.acceptRingingCall()
메서드를 사용하여 걸려오는 전화를 앱에서 처리할 수 있습니다. - 앱에
READ_PHONE_NUMBERS
권한이 있으면 기기에 저장된 전화 번호를 읽을 수 있습니다.
이런 권한은 모두 위험으로 분류되고 PHONE
권한 그룹에 속합니다.
새로운 Account Access 및 Discovery API
Android 8.0에서는 앱이 사용자 계정에 액세스하는 방식을 여러 가지로 개선합니다. 인증자는 자신이 관리하는 계정을 어떤 앱에는 숨기고 어떤 앱에는 표시할지 여부를 결정하기 위해 고유한 정책을 사용할 수 있습니다. Android 시스템은 어떤 애플리케이션이 특정 계정에 액세스할 수 있는지를 추적합니다.
이전의 Android 버전에서 사용자 계정 목록을 추적하려는 앱은 관련 없는 유형의 계정을 포함하여 모든 계정을 업데이트해야 했습니다. Android 8.0에서 addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[])
메서드가 추가되었습니다. 이 메서드를 사용하는 앱은 계정 변경 사항을 수신해야 하는 계정 유형 목록을 지정할 수 있습니다.
API 변경 사항
AccountManager는 인증자가 계정을 볼 수 있는 앱을 관리하도록 도와주는 6개의 새로운 메서드를 제공합니다.
setAccountVisibility(android.accounts.Account, java.lang.String, int)
: 특정 사용자 계정과 패키지 조합의 가시성 수준을 설정합니다.-
getAccountVisibility(android.accounts.Account, java.lang.String)
: 특정 사용자 계정과 패키지 조합의 가시성 수준을 가져옵니다. -
getAccountsAndVisibilityForPackage(java.lang.String, java.lang.String)
: 인증자가 주어진 패키지의 계정과 가시성 수준을 가져올 수 있습니다. -
getPackagesAndVisibilityForAccount(android.accounts.Account)
: 인증자가 주어진 계정의 저장된 가시성 값을 가져올 수 있습니다. -
addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.String, java.lang.Integer>)
: 인증자가 계정의 가시성 값을 초기화할 수 있습니다. -
addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[])
:OnAccountsUpdateListener
리스너를AccountManager
객체에 추가합니다. 기기의 계정 목록이 변경될 때마다 시스템이 이 리스너를 호출합니다.
Android 8.0는 setAccountVisibility(android.accounts.Account, java.lang.String, int)
메서드를 사용하여 설정되지 않았던 애플리케이션의 가시성 수준을 지정하기 위해 2개의 특수 Package Name 값을 도입합니다. PACKAGE_NAME_KEY_LEGACY_VISIBLE
가시성 값은 GET_ACCOUNTS
권한을 가진 앱, Android 8.0보다 낮은 Android 버전을 대상으로 하는 앱, 또는 임의의 Android 버전을 대상으로 하는 인증자와 서명이 일치하는 앱에 적용됩니다. PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE
은 이전에 설정되지 않은 앱에 대해 그리고 PACKAGE_NAME_KEY_LEGACY_VISIBLE
이 적용되지 않는 앱에 대해 기본 가시성 값을 제공합니다.
새로운 Account Access 및 Discovery API에 대한 자세한 정보는 AccountManager
및 OnAccountsUpdateListener
를 참조하세요.
Google 안전 브라우징 API
웹 브라우징의 보안 강화를 위해 이제 WebView
클래스에 안전 브라우징 API가 포함됩니다. 자세한 내용은 Google 안전 브라우징 API를 참조하세요.
테스트
계측 테스트
Android 8.0에서는 앱의 계측 테스트를 위해 다음과 같은 추가적인 지원을 제공합니다.
비기본 앱 프로세스에 대해 실행
이제 앱의 기본 프로세스를 벗어난 프로세스에 대해 특정 계측 테스트가 실행되도록 지정할 수 있습니다. 이 구성은 다른 프로세스에서 실행되는 여러 액티비티가 앱에 포함된 경우 유용합니다.
비기본 프로세스 계측을 정의하려면 매니페스트 파일로 이동한 다음, 원하는 <instrumentation>
요소로 이동합니다. android:targetProcess
특성을 추가하고 그 값을 다음 중 하나로 설정합니다.
- 특정 프로세스의 이름.
- 쉼표로 구분된 프로세스 이름 목록.
- 와일드카드(
"*"
): 와일드카드는android:targetPackage
특성에 지정된 패키지의 코드를 실행하는 모든 시작 프로세스에 대해 계측이 수행되도록 합니다.
계측 테스트가 수행되는 동안, getProcessName()
을 호출하여 어떤 프로세스가 테스트 중인지 확인할 수 있습니다.
테스트 중에 결과 보고
이제 계측 테스트 후가 아니라 계측 테스트가 수행되는 중에 addResults()
를 호출하여 결과를 보고할 수 있습니다.
테스트용 가짜 인텐트
앱의 액티비티에 대해 격리되고 독립적인 UI 테스트를 더 쉽게 생성할 수 있도록, Android 8.0에서는 onStartActivity()
메서드를 도입합니다. Instrumentation.ActivityMonitor
클래스의 사용자설정 서브클래스에서 이 메서드를 재정의하여 테스트 클래스가 호출하는 특정 인텐트를 처리합니다.
테스트 클래스가 인텐트를 호출할 때, 이 메서드는 인텐트 자체를 실행하는 대신 스텁 Instrumentation.ActivityResult
객체를 반환합니다. 개발자는 테스트에 이런 가짜 인텐트 로직을 사용함으로써 자신의 액티비티가 다른 액티비티나 전혀 다른 앱으로 전달하는 인텐트를 준비하고 처리하는 방식에 초점을 맞출 수 있습니다.
런타임 및 도구
플랫폼 최적화
Android 8.0는 플랫폼에 런타임 및 기타 최적화를 적용하여 많은 성능 개선을 이룹니다. 이러한 최적화에는 동시 압축 가비지 수집, 더욱 효율적인 메모리 사용, 코드 위치 등이 포함됩니다.
이러한 최적화를 통해 부팅 시간이 단축될 뿐 아니라, OS와 앱 모두 성능이 향상됩니다.
업데이트된 Java 지원
Android 8.0에서는 다음과 같이 여러 가지 추가적인 OpenJDK Java API에 대한 지원이 추가됩니다.
- OpenJDK 8의
java.time
. - OpenJDK 7의
java.nio.file
및java.lang.invoke
.
새로 추가된 이러한 패키지 내에 있는 클래스와 메서드에 대해 자세히 알아보려면 API 참조 문서를 참조하세요.
Android 스튜디오에서 Java 8 언어 기능을 사용하고 싶으면 최신 미리보기 버전을 다운로드해야 합니다.
업데이트된 ICU4J Android 프레임워크 API
Android 8.0에서는 앱 개발자가 android.icu
패키지 아래에서 사용하도록 ICU4J API의 하위 집합인 ICU4J Android 프레임워크 API를 확장합니다. 이들 API는 기기에 있는 현지화 데이터를 사용하므로 APK에서 ICU4J 라이브러리를 컴파일하지 않고 APK 사용 공간을 줄일 수 있습니다.
표 1. Android에 사용되는 ICU, CLDR 및 유니코드 버전.
Android API 레벨 | ICU 버전 | CLDR 버전 | 유니코드 버전 |
---|---|---|---|
Android 7.0 (API 레벨 24), Android 7.1 (API 레벨 25) | 56 | 28 | 8.0 |
Android 8.0 | 58.2 | 30.0.3 | 9.0 |
Android 엔터프라이즈
Android 8.0가 실행되는 기기에 대해 새로운 엔터프라이즈 기능과 API가 도입되었습니다. 주요 특징은 다음과 같습니다.
- 완벽히 관리되는 기기의 작업 프로필을 통해 기업은 개인 데이터와 작업을 둘 다 관리하면서도 분리할 수 있습니다.
- API 위임을 통해 기기 소유자와 프로필 소유자가 앱 관리를 다른 애플리케이션에 할당할 수 있습니다.
- 프로비저닝 흐름에서 사용자 환경 개선은 설정 시간을 줄여줍니다(새로운 사용자설정 옵션 포함).
- 블루투스, Wi-Fi, 백업 및 보안을 위한 새로운 컨트롤을 통해 기업에서 더 많은 기기를 관리할 수 있습니다. 네트워크 활동 로그 기록은 기업에서 문제를 추적하도록 도와줍니다.
이러한 특징과 기타 새로운 Android 엔터프라이즈 API 및 기능에 대해 알아보려면 Android 엔터프라이즈를 참조하세요.