동작 변경사항: API 레벨 28+를 타겟팅하는 앱

Android 9(API 레벨 28)에서는 Android 시스템에 많은 변경사항이 도입됩니다. 다음 동작 변경사항은 API 수준 28 이상을 타겟팅하는 앱에만 적용됩니다. targetSdkVersion를 API 수준 28 이상으로 설정하는 앱은 이러한 동작을 올바르게 지원하도록 앱을 수정해야 합니다(해당하는 경우).

타겟팅하는 API 수준과 관계없이 Android 9에서 실행되는 모든 앱에 영향을 미치는 변경사항은 동작 변경사항: 모든 앱을 참고하세요.

포그라운드 서비스

Android 9 이상을 타겟팅하고 포그라운드 서비스를 사용하는 앱은 FOREGROUND_SERVICE 권한을 요청해야 합니다. 이는 정상적인 권한이므로 시스템은 요청 앱에 자동으로 권한을 부여합니다.

Android 9 이상을 타겟팅하는 앱에서 FOREGROUND_SERVICE를 요청하지 않고 포그라운드 서비스를 만들려고 하면 시스템에서 SecurityException이 발생합니다.

개인정보 보호 변경사항

앱이 Android 9를 타겟팅하는 경우 다음 동작 변경사항에 유의해야 합니다. 이러한 기기 일련번호 및 DNS 정보 업데이트는 사용자 개인 정보 보호를 강화합니다.

빌드 일련번호 지원 중단

Android 9에서 사용자 개인 정보 보호를 위해 Build.SERIAL는 항상 "UNKNOWN"로 설정됩니다.

앱에서 기기의 하드웨어 일련번호에 액세스해야 한다면 대신 READ_PHONE_STATE 권한을 요청한 다음 getSerial()를 호출해야 합니다.

DNS 개인정보 보호

Android 9을 대상으로 하는 앱은 비공개 DNS API를 준수해야 합니다. 특히 앱은 시스템 리졸버가 TLS를 통해 DNS를 실행하는 경우 모든 내장 DNS 클라이언트가 시스템과 동일한 호스트 이름에 대해 암호화된 DNS를 사용하거나 시스템 리졸버를 위해 사용 중지되도록 해야 합니다.

프레임워크 보안 변경사항

Android 9에는 앱의 보안을 개선하는 여러 동작 변경사항이 포함되어 있지만 이러한 변경사항은 앱이 API 수준 28 이상을 타겟팅하는 경우에만 적용됩니다.

기본적으로 네트워크 TLS 사용

앱에서 Android 9 이상을 타겟팅하면 isCleartextTrafficPermitted() 메서드가 기본적으로 false를 반환합니다. 앱이 특정 도메인에 일반 텍스트를 사용 설정해야 한다면 앱의 네트워크 보안 구성에서 해당 도메인의 cleartextTrafficPermittedtrue로 명시적으로 설정해야 합니다.

프로세스별로 구분되는 웹 기반 데이터 디렉터리

Android 9에서 앱 안정성과 데이터 무결성을 개선하기 위해 앱은 여러 프로세스 간에 단일 WebView 데이터 디렉터리를 공유할 수 없습니다. 일반적으로 이러한 데이터 디렉터리에는 쿠키, HTTP 캐시, 그리고 웹 탐색과 관련된 기타 영구 저장소와 임시 저장소가 저장됩니다.

대부분의 경우 앱은 한 프로세스에서만 WebViewCookieManager과 같은 android.webkit 패키지의 클래스를 사용해야 합니다. 예를 들어 WebView를 사용하는 모든 Activity 객체를 동일한 프로세스로 이동해야 합니다. 앱의 다른 프로세스에서 disableWebView()를 호출하여 '한 프로세스만' 규칙을 더 엄격하게 적용할 수 있습니다. 이 호출은 종속 라이브러리에서 호출되더라도 WebView가 실수로 다른 프로세스에서 초기화되지 않도록 합니다.

앱이 둘 이상의 프로세스에서 WebView 인스턴스를 사용해야 하는 경우 해당 프로세스에서 WebView의 특정 인스턴스를 사용하기 전에 WebView.setDataDirectorySuffix() 메서드를 사용하여 각 프로세스에 고유한 데이터 디렉터리 접미사를 할당해야 합니다. 이 메서드는 각 프로세스의 웹 데이터를 앱의 데이터 디렉터리 내 자체 디렉터리에 배치합니다.

앱별 SELinux 도메인

Android 9 이상을 타겟팅하는 앱은 어디서나 액세스 가능한 Unix 권한을 사용하는 다른 앱과 데이터를 공유할 수 없습니다. 이 변경사항으로 Android 애플리케이션 샌드박스의 무결성, 특히 앱의 비공개 데이터에 해당 앱에서만 액세스할 수 있어야 한다는 요구사항이 개선됩니다.

다른 앱과 파일을 공유하려면 콘텐츠 제공자를 사용하세요.

연결 변경사항

연결 데이터 카운트 및 다중 경로

Android 9 이상을 타겟팅하는 앱 내에서 시스템은 현재 기본값이 아닌 네트워크의 네트워크 트래픽(예: 기기가 Wi-Fi에 연결되어 있을 때의 이동통신 트래픽)을 집계하고 NetworkStatsManager 클래스의 메서드를 제공하여 해당 트래픽을 쿼리합니다.

특히 이제 getMultipathPreference()는 앞서 언급한 네트워크 트래픽을 기반으로 값을 반환합니다. Android 9부터 이 메서드는 모바일 데이터에 true를 반환하지만 하루에 일정량 이상의 트래픽이 누적되면 false이 반환되기 시작합니다. Android 9에서 실행되는 앱은 이 메서드를 호출하고 이 힌트를 고려해야 합니다.

이제 ConnectivityManager.NetworkCallback 클래스가 VPN에 관한 정보를 앱에 전송합니다. 이 변경사항으로 인해 앱은 동기 호출과 비동기 호출을 혼용하거나 제한된 API를 사용하지 않고도 연결 이벤트를 수신 대기할 수 있습니다. 또한 이는 기기가 여러 Wi-Fi 네트워크나 여러 이동통신 네트워크에 동시에 연결되어 있을 때 정보 전송이 예상대로 작동한다는 것을 의미합니다.

Apache HTTP 클라이언트 지원 중단

Android 6.0에서는 Apache HTTP 클라이언트에 대한 지원이 삭제되었습니다. Android 9부터는 이 라이브러리가 bootclasspath에서 삭제되고 기본적으로 앱에서 사용할 수 없습니다.

Android 9 이상을 타겟팅하는 앱에서 Apache HTTP 클라이언트를 계속 사용하려면 다음을 AndroidManifest.xml에 추가하면 됩니다.

<uses-library android:name="org.apache.http.legacy" android:required="false"/>

런타임 Apache 라이브러리를 사용하는 대신 앱에서 자체 버전의 org.apache.http 라이브러리를 APK에 번들로 묶을 수 있습니다. 이 경우 런타임에서 제공되는 클래스와의 클래스 호환성 문제를 방지하기 위해 Jar Jar와 같은 유틸리티를 사용하여 라이브러리를 리패키징해야 합니다.

UI 변경사항

뷰 포커스

0 영역(너비나 높이가 0)이 있는 뷰는 포커스가 불가능합니다.

또한 터치 모드에서는 활동이 더 이상 초기 포커스를 암시적으로 할당하지 않습니다. 대신 원하는 경우 초기 포커스를 명시적으로 요청하는 것은 개발자의 몫입니다.

CSS RGBA 16진수 값 처리

Android 9 이상을 타겟팅하는 앱은 4자리 및 8자리 16진수 CSS 색상을 처리하기 위한 초안 CSS 색상 모듈 레벨 4 동작을 사용 설정해야 합니다.

CSS 색상 모듈 수준 4는 버전 52부터 Chrome에서 지원되었지만, 현재는 WebView에서 이 기능을 사용 중지합니다. 기존 Android 애플리케이션의 경우 렌더링 오류를 야기할 수 있는 Android 순서 지정 (ARGB)에 32비트 16진수 색상이 포함되어 있기 때문입니다.

예를 들어 #80ff8080 색상은 API 수준 27 이하를 타겟팅하는 앱의 경우 현재 WebView에서 불투명한 연한 빨간색 (#ff8080)으로 렌더링됩니다. 선행 구성요소 (Android에서는 알파 구성요소로 해석될 수 있음)는 현재 무시됩니다. 앱이 API 수준 28 이상을 타겟팅하면 #80ff8080은 50% 투명한 연녹색 (#80ff80)으로 해석됩니다.

file: URI용 MIME 유형 스니핑

Android 9 이전의 Android 버전은 파일 콘텐츠에서 MIME 유형을 추론할 수 있습니다. Android 9 (API 수준 28)부터는 앱이 WebView에서 file: URI를 로드할 때 올바른 파일 확장자를 사용해야 합니다.

파일 콘텐츠를 사용하여 MIME 유형을 유추하는 것은 보안 버그의 원인이 될 수 있으며 최신 브라우저에서는 일반적으로 허용되지 않습니다.

파일에 .html, .txt, .js 또는 .css와 같은 인식된 파일 확장자가 있는 경우 MIME 유형은 확장자에 의해 결정됩니다. 파일에 확장자가 없거나 인식할 수 없는 파일인 경우 MIME 유형은 일반 텍스트입니다.

예를 들어 file:///sdcard/test.html와 같은 URI는 HTML로 렌더링되지만 file:///sdcard/test와 같은 URI는 파일에 HTML 데이터가 포함되어 있더라도 일반 텍스트로 렌더링됩니다.

문서 스크롤 요소

Android 9는 문서의 루트 요소가 스크롤 요소인 경우를 적절하게 처리합니다. 이전 버전에서는 스크롤 위치가 본문 요소에 설정되었으며 루트 요소에는 0 스크롤 값이 있었습니다. Android 9는 스크롤 요소가 루트 요소가 되는 표준 호환 동작을 사용 설정합니다.

또한 document.body.scrollTop, document.body.scrollLeft, document.documentElement.scrollTop 또는 document.documentElement.scrollLeft에 직접 액세스하는 동작은 타겟 SDK에 따라 달라집니다. 표시 영역 스크롤 값에 액세스하려면 document.scrollingElement를 사용하세요(가능한 경우).

일시정지된 앱의 알림

Android 9 이전에는 정지된 앱의 알림이 취소되었습니다. Android 9부터는 앱이 다시 시작될 때까지 정지된 앱의 알림이 숨겨집니다.