Save the date! Android Dev Summit is coming to Sunnyvale, CA on Oct 23-24, 2019.

동작 변경사항: 모든 앱

Android 9(API 레벨 28)에서는 Android 시스템에 많은 변경사항이 도입됩니다. 다음과 같은 동작 변경사항은 Android 9 플랫폼에서 실행되는 모든 앱에 적용되며, 대상으로 하는 API 레벨과는 상관이 없습니다. 모든 개발자는 이러한 변경사항을 검토해야 하며 이를 적절히 지원하도록 앱을 수정해야 합니다.

API 레벨 28 이상을 대상으로 하는 앱에만 영향을 미치는 변경사항의 경우, 동작 변경사항: API 레벨 28+를 대상으로 하는 앱을 참조하세요.

전원 관리

Android 9에서는 기기 전원 관리를 개선하기 위한 새로운 기능을 소개합니다. 이러한 변경사항은 Android 9 이전에 이미 있는 기능들과 더불어, 가장 필요한 앱에 시스템 리소스가 분배되도록 보장합니다.

자세한 내용은 전원 관리를 참조하세요.

개인정보 보호정책 변경사항

Android 9은 사용자 개인정보 보호를 강화하기 위해 여러 가지 동작 변경사항을 적용합니다. 예를 들어, 백그라운드 앱의 기기 센서 액세스를 제한하고, Wi-Fi 스캔으로 검색되는 정보를 제한하고, 전화 통화, 전화 상태, Wi-Fi 스캔과 관련하여 새로운 권한 규칙과 권한 그룹을 적용합니다.

이러한 변경사항은 대상 SDK 버전과 무관하게 Android 9을 실행하는 모든 앱에 영향을 미칩니다.

백그라운드에서 센서 액세스 제한

Android 9에서는 백그라운드 앱이 사용자 입력과 센서 데이터에 액세스하는 능력을 제한합니다. Android 9이 실행되는 기기에서 앱이 백그라운드로 실행 중인 경우, 시스템은 다음과 같은 제한을 앱에 적용합니다.

  • 앱이 마이크나 카메라에 액세스할 수 없습니다.
  • 연속 보고 모드를 사용하는 센서(예: 가속도계 및 자이로스코프)는 이벤트를 수신하지 않습니다.
  • 변경 시 또는 원샷 보고 모드를 사용하는 센서는 이벤트를 수신하지 않습니다.

Android 9이 실행되는 기기에서 앱이 센서 이벤트를 감지해야 하는 경우, 포그라운드 서비스를 사용하세요.

통화 로그 액세스 제한

Android 9에서는 CALL_LOG 권한 그룹을 도입하고 READ_CALL_LOG, WRITE_CALL_LOGPROCESS_OUTGOING_CALLS 권한을 이 그룹으로 이동합니다. 이전의 Android 버전에서 이 권한들은 PHONE 권한 그룹에 위치했습니다.

CALL_LOG 권한 그룹은 사용자가 앱에서 전화 통화 기록을 보고 전화번호를 식별하는 등과 같이 전화 통화와 관련된 민감한 정보에 액세스하는 데 필요한 강화된 제어 능력과 가시성을 제공합니다.

앱에서 통화 로그에 액세스해야 하거나 발신 통화를 처리해야 할 경우 CALL_LOG 권한 그룹으로부터 명시적으로 이 권한을 요청해야 합니다. 그렇지 않으면 SecurityException이 발생합니다.

참고: 이런 권한은 그룹이 변경되어 런타임에 부여되므로 사용자가 앱에서 전화 통화 기록 정보에 액세스하지 못하도록 거부할 수 있습니다. 이 경우 앱이 정보에 액세스하지 못하더라도 이를 적절히 처리할 수 있어야 합니다.

앱이 이미 런타임 권한 모범 사례를 준수하고 있다면 권한 그룹의 변경을 처리할 수 있습니다.

전화번호 액세스 제한

Android 9에서 실행되는 앱은 사용 사례에 필요한 다른 권한 외에도 먼저 READ_CALL_LOG 권한을 얻어야 전화번호 또는 전화 상태를 읽을 수 있습니다.

수신 및 발신 통화와 관련된 전화번호는 수신 전화 및 발신 전화 등에 대한 전화 상태 브로드캐스트 에서 확인할 수 있고 PhoneStateListener 클래스에서 액세스할 수 있습니다. 그러나 READ_CALL_LOG 권한이 없으면 PHONE_STATE_CHANGED 브로드캐스트와 PhoneStateListener를 통해 제공되는 전화번호 필드가 비어 있습니다.

전화 상태에서 전화번호를 읽으려면 사용 사례에 따라 필요한 권한을 요청하도록 앱을 업데이트하십시오.

Wi-Fi 위치 및 연결 정보 액세스 제한

Android 9은 이전 버전보다 앱이 Wi-Fi를 스캔하는 데 필요한 권한 요구사항이 엄격해졌습니다. 자세한 내용은 Wi-Fi 스캔 제한을 참조하세요.

유사한 제한이 getConnectionInfo() 메서드에도 적용됩니다. 이 메서드는 현재 Wi-Fi 위치를 설명하는 WifiInfo 객체를 반환합니다. 호출하는 앱에 다음과 같은 권한이 있을 경우 이 객체의 메소드만 사용하여 SSID 및 BSSID 값을 검색할 수 있습니다.

  • ACCESS_FINE_LOCATION 또는 ACCESS_COARSE_LOCATION
  • ACCESS_WIFI_STATE

SSID 또는 BSSID를 검색하려면 기기에서 위치 서비스가 활성화되어 있어야 합니다(Settings > Location 아래).

Wi-Fi 서비스 메서드에서 정보 삭제

Android 9에서 다음 이벤트와 브로드캐스트는 사용자 위치 또는 개인 식별 데이터와 관련된 정보를 수신하지 않습니다.

Wi-Fi의 NETWORK_STATE_CHANGED_ACTION 시스템 브로드캐스트에는 SSID(이전의 EXTRA_SSID), BSSID (이전의 EXTRA_BSSID) 또는 연결 정보(이전의 EXTRA_NETWORK_INFO)가 포함되지 않습니다. 앱에 이 정보가 필요하면 대신 getConnectionInfo()를 호출하세요.

기기 위치 설정에 따라 전화 정보 제공

사용자가 Android 9이 실행되는 기기에서 기기 위치를 비활성화했다면 다음의 메서드는 결과를 제공하지 않습니다.

비 SDK 인터페이스 사용에 대한 제한

앱 안정성과 호환성을 보장하기 위해 플랫폼에서는 일부 비 SDK 메서드와 필드의 사용을 제한합니다. 이러한 제한은 리플렉션을 통해 이들 메서드와 필드에 직접 액세스를 시도하든 아니면 JNI를 사용하든 간에 모두 적용됩니다. Android 9에서는 앱이 이러한 제한된 인터페이스에 계속해서 액세스할 수 있으며, 플랫폼에서는 관심을 끌기 위해 알림 메시지와 로그 항목을 사용합니다. 이러한 알림 메시지가 앱에 나타나는 경우에는, 제한된 인터페이스가 아닌 다른 구현 전략을 추진하는 것이 중요합니다. 대체 전략이 현실성이 없다고 느끼는 경우에는, 해당 제한을 재고하도록 요청하기 위해 버그를 제출할 수도 있습니다.

비 SDK 인터페이스에 대한 제한 에는 더욱 중요한 정보가 들어 있습니다. 앱이 제대로 작동하도록 보장하려면 이 제한을 검토해야 합니다.

보안 동작 변경사항

기기 보안 변경사항

Android 9은 앱의 대상 버전과는 무관하게 앱의 보안을 개선하는 여러 가지 기능을 추가합니다.

TLS 구현 변경사항

Android 9에서는 다음과 같이 시스템의 TLS 구현이 여러 차례 변경되었습니다.

  • SSLSocket의 인스턴스가 생성되는 동안 연결에 실패할 경우, 시스템에서 NullPointerException 대신 IOException을 발생시킵니다.
  • 어떤 close_notify 경고가 발생하더라도 SSLEngine 클래스가 이를 깔끔하게 처리합니다.

Android 앱에서 안전한 웹 요청을 하는 자세한 방법은 HTTPS 예시를 참조하세요.

더욱 엄격해진 SECCOMP 필터

Android 9에서는 앱에 사용 가능한 시스템 호출을 더욱 엄격히 제한합니다. 이 동작은 Android 8.0(API 레벨 26)에 포함된 SECCOMP 필터의 확장 프로그램입니다.

참고: 이 변경사항은 권한을 가진 syscall을 사용하는 앱에만 영향을 미칩니다.

암호화 변경사항

Android 9에서는 암호화 알고리즘의 구현과 처리에 여러 가지 변화가 있습니다.

매개변수 및 알고리즘의 Conscrypt 구현

Android 9은 Conscrypt에서 알고리즘 매개변수의 추가적인 구현을 제공합니다. 이들 매개변수에는 AES, DESEDE, OAEP 및 EC가 포함됩니다. 이러한 매개변수의 Bouncy Castle 버전과 다수의 알고리즘이 Android 9에서 지원이 중단되었습니다.

참고: Conscrypt의 EC 매개변수 구현에서는 명명된 곡선만 지원합니다.

Android 8.1(API 레벨 27) 이하를 대상으로 하는 앱의 경우, 지원 중단된 알고리즘 중 하나의 Bouncy Castle 구현을 요청하면 경고가 표시됩니다. 그러나 Android 9을 대상으로 하는 경우에는 이러한 요청은 각각 NoSuchAlgorithmException을 발생시킵니다.

기타 변경사항

Android 9에서는 암호화와 관련된 여러 가지 변경사항이 도입됩니다.

  • PBE 키를 사용하는 경우, Bouncy Castle이 초기화 벡터(IV)를 예상하는 데 앱이 이것을 제공하지 않으면 경고가 표시됩니다.
  • Conscrypt의 ARC4 암호화 구현에서는 ARC4/ECB/NoPadding 또는 ARC4/NONE/NoPadding을 지정할 수 있습니다.
  • Crypto JCA(Java Cryptography Architecture) 제공자는 제거되었습니다. 그 결과, 앱이 SecureRandom.getInstance("SHA1PRNG", "Crypto")를 호출하면 NoSuchProviderException 이 발생합니다.
  • 앱이 키 구조보다 더 큰 버퍼로부터 RSA 키를 파싱하는 경우, 더 이상 예외가 발생하지 않습니다.

Android 암호화 기능의 사용 방법에 대한 자세한 내용은 암호화를 참조하세요.

Android 보안 암호화된 파일은 더 이상 지원되지 않음

Android 9에서는 Android 보안 암호화 파일(ASEC)에 대한 지원이 완전히 제거됩니다.

Android 2.2 (API 레벨 8)에서 Android는 SD 카드의 앱 기능을 지원하기 위해 ASEC를 도입했습니다. Android 6.0(API 레벨 23)에서 플랫폼은 개발자가 ASEC 대신 사용할 수 있는 어댑터블 스토리지 기기 기술을 도입했습니다.

ICU 라이브러리에 대한 업데이트

Android 9은 ICU 라이브러리의 버전 60을 사용합니다. Android 8.0(API 레벨 26)과 Android 8.1(API 레벨 27)은 ICU 58을 사용합니다.

ICU는 android.icu package 아래에 공개 API를 제공하는 데 사용하고 내부적으로 Android 플랫폼에서 국제화 지원에 사용합니다. 예를 들어, java.util, java.textandroid.text.format에서 Android 클래스를 구현하는 데 사용됩니다.

ICU 60 업데이트에는 ICU 59 및 ICU 60 출시 노트에 설명된 것과 같이 Emoji 5.0 데이터 지원 및 개선된 날짜/시간 형식 등의 사소하면서도 유용한 변경사항이 다수 포함되어 있습니다.

이 업데이트에서 특기할 만한 변경사항은 다음과 같습니다.

  • 플랫폼에서 시간대를 처리하는 방식이 변경되었습니다.
    • 플랫폼에서 GMT 및 UTC를 더욱 잘 처리하며, UTC는 더 이상 GMT와 동의어가 아닙니다.

      이제 ICU는 GMT 및 UTC에 변환된 시간대 이름을 제공합니다. 이러한 변경은 "GMT", "Etc/GMT", "UTC", "Etc/UTC" 및 "Zulu"와 같은 시간대의 android.icu 서식 및 파싱 동작에 영향을 미칩니다.

    • 이제 java.text.SimpleDateFormat에서 ICU를 사용하여 UTC /GMT에 표시 이름을 제공합니다. 즉,
      • zzzz 서식은 많은 로케일에 대해 현지화된 긴 문자열을 생성합니다. 이전에는 UTC에 대해 "UTC"를 생성했고 GMT에 대해 "GMT+00:00"와 같은 문자열을 생성했습니다.
      • zzzz 파싱은 "Universal Coordinated Time" 및 "Greenwich Mean Time"과 같은 문자열을 인식합니다.
      • 모든 언어에서 zzzz의 출력이 "UTC" 또는 "GMT+00:00"이라고 가정하는 경우, 앱에서 호환성 문제가 발생할 수도 있습니다.
    • java.text.DateFormatSymbols.getZoneStrings()의 동작이 다음과 같이 변경되었습니다.
      • 이제 UTC 및 GMT에서 SimpleDateFormat와 같은 긴 이름을 가집니다. UTC 시간대의 DST 변형 시간대 이름(예: "UTC", "Etc/UTC" 및 "Zulu")은 GMT+00:00이 됩니다. 사용 가능한 이름이 없는 경우 이 이름은 하드코딩된 문자열인 UTC 대신 표준 대체 이름이 됩니다.
      • 일부 시간대 ID는 다른 시간대의 동의어로 올바르게 인식되므로, Android는 오래된 시간대 ID에 대한 문자열을 찾습니다(예: Eire). 이전에는 이 문제를 해결할 수 없었습니다.
    • 아시아/하노이 시간대는 더 이상 인식되지 않습니다. 이 때문에 java.util.TimeZones.getAvailableIds()는 이 값을 반환하지 않으며 java.util.TimeZone.getTimeZone()은 이를 인식하지 못합니다. 이 동작은 기존 android.icu 동작과 일치합니다.
  • android.icu.text.NumberFormat.getInstance(ULocale, PLURALCURRENCYSTYLE).parse(String) 메서드의 경우 합법적 통화 텍스트를 파싱할 때에도 ParseException이 발생할 수 있습니다. 이 문제를 피하려면 스타일의 통화 텍스트에 NumberFormat.parseCurrency를사용하세요. 이 메서드는 Android 7.0(API 레벨 24) 이후 버전에서PLURALCURRENCYSTYLE 사용할 수 있습니다.

Android 테스트 변경사항

Android 9에서는 Android Test 프레임워크의 라이브러리와 클래스 구조에 여러 변경사항이 도입되었습니다. 이런 변경사항은 개발자가 프레임워크 지원 공개 API를 사용하는 데 도움을 주지만 타사 라이브러리나 맞춤 로직을 사용하여 테스트를 빌드하고 실행할 때 더욱 유연성을 발휘할 수 있게 합니다.

프레임워크에서 라이브러리 제거

Android 9에서는 JUnit 기반 클래스를 android.test.base, android.test.runner, android.test.mock의 세 가지 라이브러리로 재구성했습니다. 이러한 변경으로 인해 프로젝트 종속성과 가장 잘 호환되는 JUnit 버전에 대해 테스트를 실행할 수 있게 되었습니다. 이 JUnit 버전은 android.jar가 제공하는 버전과 다를 수 있습니다.

JUnit 기반 클래스가 이러한 라이브러리로 구성된 방식과 테스트 작성 및 실행을 위해 앱 프로젝트를 준비하는 방법에 대한 자세한 정보는 Android Test를 위한 프로젝트 설정을 참조하세요.

테스트 모음 빌드 변경사항

TestSuiteBuilder 클래스의 addRequirements() 메서드가 제거되었고 TestSuiteBuilder 클래스가 지원 중단되었습니다. addRequirements() 메서드는 유형이 숨겨진 API인 인수를 개발자가 제공해야 하며, 이 API가 무효화됩니다.

Java UTF 디코더

UTF-8은 Android의 기본 문자 집합입니다. UTF-8 바이트 시퀀스는 String 생성자(예: String(byte[] bytes))에 의해 디코딩될 수 있습니다.

Android 9의 UTF-8 디코더는 이전 버전보다 더욱 엄격하게 Unicode 표준 을 준수합니다. 변경사항에는 다음 내용이 포함됩니다.

  • 비최단(non-shortest) 형식의 UTF-8(예: <C0, AF>)은 잘못된 형식으로 간주됩니다.
  • 대리(surrogate) 형식의 UTF-8(예: U+D800..U+DFFF)는 잘못된 형식으로 간주됩니다.
  • 최대 서브파트는 단일 U+FFFD로 대체됩니다. 예를 들어, 바이트 시퀀스 "41 C0 AF 41 F4 80 80 41"에서 최대 서브파트는 "C0," "AF" 및 "F4 80 80"입니다. "F4 80 80"은 "F4 80 80 80"의 초기 서브시퀀스가 될 수 있지만, "C0"은 올바른 형식의 코드 단위 시퀀스의 초기 서브시퀀스가 될 수 없습니다. 따라서 출력은 "A\ufffd\ufffdA\ufffdA"여야 합니다.
  • 수정된 UTF-8 / CESU-8 시퀀스를 Android 9 이상에서 디코딩하려면 DataInputStream.readUTF() 메서드나 NewStringUTF() JNI 메서드를 사용하세요.

인증서를 사용하여 호스트 이름 확인

RFC 2818에서는 인증서와 도메인 이름을 일치시키기 위한 두 가지 방법에 대해 설명합니다. 즉, subjectAltName(SAN) 확장 내에 있는 이름을 사용하거나 SAN 확장이 없는 경우 commonName(CN)으로 대체됩니다.

그러나 CN으로의 대체는 RFC 2818에서 지원이 중단되었습니다. 이러한 이유로 Android에서는 더 이상 CN을 사용하여 대체할 수 없습니다. 호스트 이름을 확인하기 위해 서버는 일치하는 SAN이 포함된 인증서를 제공해야 합니다. 호스트 이름과 일치하지 않는 SAN이 포함된 인증서는 더 이상 신뢰할 수 없습니다.

네트워크 주소 조회 시 네트워크 위반이 발생할 수 있음

이름 확인을 요구하는 네트워크 주소 조회에는 네트워크 I/O가 포함될 수 있으며 그러므로 이 조회는 차단 작업으로 간주됩니다. 메인 스레드의 차단 작업은 일시 중지나 버벅거림 현상을 유발할 수 있습니다.

StrictMode 클래스는 개발자가 코드에서 문제를 감지하도록 도와주는 개발 도구입니다.

Android 9 이상에서 StrictMode는 이름 확인을 요구하는 네트워크 주소 조회로부터 발생하는 네트워크 위반을 감지합니다.

StrictMode를 활성화한 상태로 앱을 내보내서는 안 됩니다. 그렇게 할 경우 네트워크 위반을 감지하는 정책을 가져오기 위해 NetworkOnMainThreadException 또는 detectNetwork() 메서드를 사용할 때, 앱에서 detectAll()과 같은 새로운 예외가 발생할 수 있습니다.

숫자 IP 주소 확인은 차단 작업으로 간주되지 않습니다. 숫자 IP 주소 확인은 Android 9 이전 버전과 동일하게 작동합니다.

소켓 태그 지정

Android 9보다 낮은 플랫폼 버전에서 setThreadStatsTag() 메서드를 사용하여 소켓에 태그를 다는 경우, 바인더 IPCParcelFileDescriptor 컨테이너와 함께 사용하여 또 다른 프로세스로 전송될 때 이 소켓의 태그가 해제됩니다.

Android 9 이상에서는 바인더 IPC를 사용하여 또 다른 프로세스로 전송될 때 소켓 태그가 유지됩니다. 이러한 변경은 네트워크 트래픽 통계에 영향을 미칠 수 있습니다(예: queryDetailsForUidTag() 메서드 사용 시).

다른 프로세스로 전송한 소켓의 태그를 제거하는 이전 버전의 동작을 유지하고 싶다면 소켓을 전송하기 전에 untagSocket()를 호출하세요.

소켓에서 사용 가능한 바이트 크기가 보고됨

shutdownInput() 메서드를 호출한 다음 available() 메서드를 호출하면 0이 반환됩니다.

VPN에 대해 더욱 상세한 네트워크 성능 보고

Android 8.1(API 레벨 28) 이하에서 NetworkCapabilities 클래스는 VPNS에 대해 제한된 정보들(예: TRANSPORT_VPN) 보고하고, NET_CAPABILITY_NOT_VPN을 생략했습니다. 정보가 제한되어 있어서 VPN을 사용하면 앱 사용자에게 요금이 발생하는지 확인하기 어려웠습니다. 예를 들어, NET_CAPABILITY_NOT_METERED 체크를 통해 기본 네트워크가 데이터 통신 네트워크인지 여부를 판별할 수 없었습니다.

Android 9 이상에서는 VPN이 setUnderlyingNetworks() 메서드를 호출할 때 Android 시스템이 기본 네트워크의 전송 및 성능을 병합하고 그 결과를 VPN 네트워크의 유효한 네트워크 성능으로 반환합니다.

Android 9 이상에서는 NET_CAPABILITY_NOT_METERED를 이미 체크한 앱은 VPN 네트워크와 기본 네트워크의 네트워크 성능 정보를 수신합니다.

xt_qtaguid 폴더의 파일을 더 이상 앱에 사용할 수 없음

Android 9부터는 앱이 /proc/net/xt_qtaguid 폴더에 있는 파일을 직접 읽을 수 없게 됩니다. 그 이유는 이러한 파일이 전혀 없는 일부 기기와의 일관성을 유지하기 위해서입니다.

이러한 파일을 사용하는 공개 API(예: TrafficStatsNetworkStatsManager)는 계속 의도한 대로 작동합니다. 그러나 qtaguid_tagSocket()와 같은 지원되지 않는 cutils 함수는 다른 기기에서 의도한 대로 작동하지 않거나 '전혀' 작동하지 않을 수도 있습니다.

FLAG_ACTIVITY_NEW_TASK 요구사항이 이제 적용됨

Android 9에서는 인텐트 플래그 FLAG_ACTIVITY_NEW_TASK를 전달하지 않을 경우 비 액티비티 컨텍스트에서 액티비티를 시작할 수 없습니다. 이 플래그를 전달하지 않고 액티비티를 시작하려고 하면 액티비티가 시작되지 않고, 시스템이 로그에 메시지를 출력합니다.

참고: 플래그 요구사항은 언제나 의도된 동작이며, Android 7.0(API 레벨 24) 이전 버전부터 적용되었습니다. Android 7.0의 버그로 인해 플래그 요구사항이 적용되지 않았습니다.

화면 회전 변경사항

Android 9부터 세로 회전 모드가 상당히 변경됩니다. Android 8.0(API 레벨 26)에서 사용자는 Quick Settings 타일이나 Display 설정을 사용하여 자동 회전세로 회전 모드를 서로 전환할 수 있습니다. 세로 모드는 이름이 회전 잠금으로 변경되었고 이 모드는 자동 회전이 꺼진 경우 활성화됩니다. 자동 회전 모드에는 변화가 없습니다.

기기가 회전 잠금 모드에 있는 경우, 사용자가 맨 위에 보이는 Activity에 의해 지원되는 회전으로 화면을 잠글 수 있습니다. Activity가 항상 세로 모드로 렌더링될 것이라고 가정해서는 안됩니다. 자동 회전 모드에서 맨 위 Activity가 다중 회전으로 렌더링될 수 있다면, 이와 동일한 옵션을 회전 잠금 모드에서도 사용할 수 있어야 합니다. 단, Activity의 screenOrientation 설정에 따라 일부 예외가 있습니다(아래 표 참조).

특정 방향을 요청하는 Activity(예: screenOrientation=landscape)는 사용자 잠금 기본 설정을 무시하고 Android 8.0에서와 동일하게 동작합니다.

Android 매니페스트에서는 Activity 레벨에서 화면 방향 기본 설정을 설정할 수 있고, setRequestedOrientation()에서는 프로그래밍 방식으로 설정할 수 있습니다.

회전 잠금 모드가 작동하기 위해서는, Activity 회전 처리 시에 WindowManager가 사용하는 사용자 회전 기본 설정을 설정해야 합니다. 다음과 같은 경우 사용자 회전 기본 설정이 바뀔 수도 있습니다. 기기의 자연스러운 회전으로 돌아가려는 경향이 있습니다. 일반적으로, 전화 폼팩터 기기에서 그 방향은 세로입니다.

  • 사용자가 회전 제안을 수락하는 경우, 이 제안으로 회전 기본 설정이 변경됩니다.
  • 사용자가 강제 세로 모드 앱으로 전환하는 경우, 세로 모드로 회전 기본 설정이 변경됩니다.

다음 표에 일반적인 화면 방향에 대한 회전 동작이 요약되어 있습니다.

화면 방향 동작
unspecified, user 자동 회전 및 회전 잠금 모드에서 Activity가 세로 모드 또는 가로 모드(및 반전)로 렌더링될 수 있습니다. 세로 모드 및 가로 모드 레이아웃을 모두 지원할 것으로 예상됩니다.
userLandscape 자동 회전 및 회전 잠금 모드에서 Activity가 가로 모드 또는 반전 가로 모드로 렌더링될 수 있습니다. 가로 모드 레이아웃만을 지원할 것으로 예상됩니다.
userPortrait 자동 회전 및 회전 잠금 모드에서 Activity가 세로 모드 또는 반전 세로 모드로 렌더링될 수 있습니다. 세로 모드 레이아웃만을 지원할 것으로 예상됩니다.
fullUser 자동 회전 및 회전 잠금 모드에서 Activity가 세로 모드 또는 가로 모드(및 반전)로 렌더링될 수 있습니다. 세로 모드 및 가로 모드 레이아웃을 모두 지원할 것으로 예상됩니다.

회전 잠금 모드 사용자에게는 반전 세로 모드(대개 180º 반전)로 잠글 수 있는 옵션이 제공됩니다.
sensor, fullSensor, sensorPortrait, sensorLandscape 회전 잠금 모드 기본 설정이 무시되고 자동 회전이 활성화된 것처럼 처리됩니다. 이 동작은 UX를 매우 신중하게 고려하여 예외적인 경우에만 사용해야 합니다.

Apache HTTP 클라이언트 지원 중단은 비표준 ClassLoader가 있는 앱에 영향을 미침

Android 6.0에서는 Apache HTTP 클라이언트에 대한 지원이 제거되었습니다. 이 변경사항은 Android 9 이상을 대상으로 하지 않는 앱에는 대부분 적용되지 않습니다. 그러나 Android 9 이상을 대상으로 하지 않더라도 비표준 ClassLoader 구조를 사용하는 일부 앱에는 적용될 수 있습니다.

명시적으로 시스템 ClassLoader에 권한을 위협하는 비표준 ClassLoader를 사용하는 앱은 영향을 받을 수 있습니다. 대신 이러한 앱은 org.apache.http.*에서 클래스를 찾을 때 ClassLoader에 권한을 위임해야 합니다. 시스템 ClassLoader에 권한을 위임하면 Android 9 이상에서 NoClassDefFoundError가 발생하며 앱이 작동하지 않습니다. 시스템 ClassLoader에서 이 클래스를 알지 못하기 때문입니다. 앞으로 이와 비슷한 문제를 예방하려면 앱이 시스템 ClassLoader에 직접 액세스하지 말고 주로 앱 ClassLoader를 통해 클래스를 로드해야 합니다.

카메라 나열

Android 9 기기에서 실행되는 앱은 getCameraIdList()를 호출하면 모든 이용 가능한 카메라를 찾아낼 수 있습니다. 기기에 후방 카메라나 전방 카메라 하나만 있는 것으로 가정하지 말아야 합니다.

예를 들어 앱에 전방 및 후방 카메라 전환 버튼이 있을 경우 선택해야 할 전방 또는 후방 카메라가 2개 이상일 수 있습니다. 카메라 목록을 보고, 각 카메라의 특성을 살펴서 사용자에게 어느 카메라를 노출할지 결정해야 합니다.