동작 변경사항: 모든 앱

Android 9(API 레벨 28)에서는 Android 시스템에 많은 변경사항이 도입됩니다. 다음과 같은 동작 변경사항은 타겟팅하는 API 수준에 관계없이 Android 9 플랫폼에서 실행되는 모든 앱에 적용됩니다. 모든 개발자는 이러한 변경사항을 검토하고 앱에 해당하는 경우 이를 적절하게 지원하도록 앱을 수정해야 합니다.

API 수준 28 이상을 타겟팅하는 앱에만 영향을 미치는 변경사항은 동작 변경사항: API 수준 28 이상을 타겟팅하는 앱을 참고하세요.

전원 관리

Android 9에서는 기기 전원 관리를 개선하는 새로운 기능을 도입합니다. 이러한 변경사항은 Android 9 이전에 이미 있었던 기능과 함께 시스템 리소스가 가장 필요한 앱에 제공될 수 있도록 합니다.

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

개인정보 보호 변경사항

사용자 개인 정보를 강화하기 위해 Android 9에서는 백그라운드 앱의 기기 센서 액세스 제한, Wi-Fi 스캔에서 가져온 정보 제한, 전화 통화, 휴대전화 상태, Wi-Fi 스캔과 관련된 새로운 권한 규칙 및 권한 그룹과 같은 여러 동작 변경사항을 도입했습니다.

이러한 변경사항은 타겟 SDK 버전에 관계없이 Android 9에서 실행되는 모든 앱에 영향을 줍니다.

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

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

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

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

통화 기록 액세스가 제한됨

Android 9에서는 CALL_LOG 권한 그룹을 도입하고 READ_CALL_LOG, WRITE_CALL_LOG, PROCESS_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 스캔 제한사항을 참고하세요.

현재 Wi-Fi 연결을 설명하는 WifiInfo 객체를 반환하는 getConnectionInfo() 메서드에도 유사한 제한사항이 적용됩니다. 호출 앱에 다음 권한이 있는 경우에만 이 객체의 메서드를 사용하여 SSID 및 BSSID 값을 가져올 수 있습니다.

  • ACCESS_FINE_LOCATION 또는 ACCESS_COARSE_LOCATION
  • ACCESS_WIFI_STATE

SSID 또는 BSSID를 검색하려면 기기에서 위치 서비스 (설정 > 위치)를 사용 설정해야 합니다.

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 구현이 여러 번 변경되었습니다.

Android 앱에서 안전한 웹 요청을 실행하는 방법에 관한 자세한 내용은 HTTPS 예시를 참고하세요.

더 엄격한 SECCOMP 필터

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

암호화 변경사항

Android 9에서는 암호화 알고리즘의 구현 및 처리에 몇 가지 변경사항이 도입되었습니다.

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

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

앱이 Android 8.1 (API 수준 27) 이하를 타겟팅하는 경우 이러한 지원 중단된 알고리즘 중 하나의 Bouncy Castle 구현을 요청할 때 경고가 표시됩니다. 그러나 Android 9를 타겟팅하는 경우 이러한 요청은 각각 NoSuchAlgorithmException을 발생시킵니다.

기타 변경사항

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

  • PBE 키를 사용할 때 Bouncy Castle에서 초기화 벡터(IV)를 예상하지만 앱에서 이를 제공하지 않으면 경고가 표시됩니다.
  • ARC4 암호화의 Conscrypt 구현을 사용하면 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.text, android.text.format에서 Android 클래스를 구현하는 데 사용됩니다.

ICU 60 업데이트에는 ICU 59 및 ICU 60 출시 노트에 설명된 대로 그림 이모티콘 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 파싱은 '협정 세계시', '그리니치 표준시'와 같은 문자열을 인식합니다.
      • 앱에서 'UTC' 또는 'GMT+00:00'이 모든 언어의 zzzz에 출력된다고 가정하면 호환성 문제가 발생할 수 있습니다.
    • java.text.DateFormatSymbols.getZoneStrings()의 동작이 변경되었습니다.
      • 이제 SimpleDateFormat와 마찬가지로 UTC 및 GMT에 긴 이름이 있습니다. UTC 시간대의 DST 변형 시간대 이름(예: 'UTC', 'Etc/UTC', 'Zulu')은 사용 가능한 이름이 없을 때 표준 대체인 GMT+00:00이 됩니다. 이는 하드코딩된 문자열 UTC이 아닙니다.
      • 일부 영역 ID는 다른 영역의 동의어로 올바르게 인식되므로 Android는 이전에 확인할 수 없었던 오래된 영역 ID(예: Eire)의 문자열을 찾습니다.
    • Asia/Hanoi가 더 이상 인식되는 시간대는 아닙니다. 따라서 java.util.TimeZones.getAvailableIds()는 이 값을 반환하지 않으며 java.util.TimeZone.getTimeZone()는 이 값을 인식하지 않습니다. 이 동작은 기존 android.icu 동작과 일치합니다.
  • android.icu.text.NumberFormat.getInstance(ULocale, PLURALCURRENCYSTYLE).parse(String) 메서드는 유효한 통화 텍스트를 파싱할 때도 ParseException을 발생시킬 수 있습니다. PLURALCURRENCYSTYLE 스타일 통화 텍스트에 Android 7.0 (API 수준 24)부터 사용할 수 있는 NumberFormat.parseCurrency를 사용하여 이 문제를 방지합니다.

Android 테스트 변경사항

Android 9에서는 Android 테스트 프레임워크의 라이브러리 및 클래스 구조에 몇 가지 변경사항이 도입되었습니다. 이러한 변경사항은 개발자가 프레임워크 지원 공개 API를 사용하는 데 도움이 되지만, 서드 파티 라이브러리 또는 맞춤 로직을 사용하여 테스트를 빌드하고 실행할 때도 더 유연해집니다.

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

Android 9에서는 JUnit 기반 클래스를 android.test.base, android.test.runner, android.test.mock의 세 가지 라이브러리로 재구성합니다. 이 변경사항을 통해 프로젝트의 종속 항목과 가장 잘 작동하는 JUnit 버전에서 테스트를 실행할 수 있습니다. 이 버전의 JUnit은 android.jar에서 제공하는 버전과 다를 수 있습니다.

JUnit 기반 클래스가 이러한 라이브러리로 구성되는 방식과 테스트 작성 및 실행을 위해 앱 프로젝트를 준비하는 방법을 자세히 알아보려면 Android 테스트용 프로젝트 설정을 참고하세요.

테스트 모음 빌드 변경사항

TestSuiteBuilder 클래스의 addRequirements() 메서드가 삭제되고 TestSuiteBuilder 클래스 자체가 지원 중단되었습니다. addRequirements() 메서드에서는 개발자가 유형이 숨겨진 API인 인수를 제공해야 했으므로 API가 유효하지 않았습니다.

Java UTF 디코더

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

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

  • <C0, AF>와 같이 가장 짧지 않은 UTF-8 형식은 잘못된 형식으로 처리됩니다.
  • 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'이어야 합니다.
  • Android 9 이상에서 수정된 UTF-8 / CESU-8 시퀀스를 디코딩하려면 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가 사용 설정된 앱을 출시해서는 안 됩니다. 이렇게 하면 detectNetwork() 또는 detectAll() 메서드를 사용하여 네트워크 위반을 감지하는 정책을 가져올 때 앱에 NetworkOnMainThreadException과 같은 예외가 발생할 수 있습니다.

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

소켓 태그 지정

Android 9 미만의 플랫폼 버전에서 setThreadStatsTag() 메서드를 사용하여 소켓에 태그가 지정된 경우 ParcelFileDescriptor 컨테이너와 함께 바인더 IPC를 사용하여 다른 프로세스로 전송될 때 소켓의 태그가 해제됩니다.

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

다른 프로세스로 전송되는 소켓의 태그를 해제하는 이전 버전의 동작을 유지하려면 소켓을 전송하기 전에 untagSocket()를 호출하면 됩니다.

소켓에서 사용 가능한 바이트 수(보고됨)

available() 메서드는 shutdownInput() 메서드를 호출한 후에 호출되면 0을 반환합니다.

VPN에 관한 더 자세한 네트워크 기능 보고

Android 8.1 (API 수준 27) 이하에서는 NetworkCapabilities 클래스가 TRANSPORT_VPN와 같은 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 폴더의 파일에 대한 직접 읽기 액세스 권한을 가질 수 없습니다. 이러한 파일이 전혀 없는 일부 기기와의 일관성을 유지하기 위해서입니다.

이러한 파일(TrafficStatsNetworkStatsManager)을 사용하는 공개 API는 계속해서 의도한 대로 작동합니다. 그러나 지원되지 않는 cutils 함수(예: qtaguid_tagSocket())는 기기마다 예상대로 작동하지 않거나 아예 작동하지 않을 수 있습니다.

이제 FLAG_ACTIVITY_NEW_TASK 요구사항이 적용됨

Android 9에서는 인텐트 플래그 FLAG_ACTIVITY_NEW_TASK를 전달하지 않으면 활동 외 컨텍스트에서 활동을 시작할 수 없습니다. 이 플래그를 전달하지 않고 활동을 시작하려고 하면 활동이 시작되지 않고 시스템에서 로그에 메시지를 출력합니다.

화면 회전 변경

Android 9부터 세로 회전 모드에 상당한 변경사항이 있습니다. Android 8.0 (API 수준 26)에서 사용자는 빠른 설정 타일 또는 디스플레이 설정을 사용하여 자동 회전세로 회전 모드 간에 전환할 수 있습니다. 세로 모드의 이름이 회전 잠금으로 변경되었으며, 이 모드는 자동 회전이 사용 중지된 상태에서 활성화됩니다. 자동 회전 모드의 변경사항은 없습니다.

기기가 회전 잠금 모드로 전환되면 사용자는 상단에 보이는 활동에 의해 지원되는 모든 회전 모드로 화면을 잠글 수 있습니다. 활동은 항상 세로 모드로 렌더링된다고 가정해서는 안 됩니다. 상단 활동을 자동 회전 모드의 여러 회전에서 렌더링할 수 있는 경우 동일한 옵션을 회전 잠금 모드에서도 사용할 수 있어야 합니다. 단, 활동의 screenOrientation 설정에 따른 일부 예외가 적용됩니다 (아래 표 참고).

특정 방향을 요청하는 활동 (예: screenOrientation=landscape)은 사용자 잠금 환경설정을 무시하고 Android 8.0과 동일한 방식으로 작동합니다.

화면 방향 환경설정은 Android 매니페스트의 Activity 수준에서 설정하거나 setRequestedOrientation()을 사용하여 프로그래매틱 방식으로 설정할 수 있습니다.

회전 잠금 모드는 WindowManager가 Activity 회전을 처리할 때 사용하는 사용자 회전 환경설정을 설정하여 작동합니다. 다음과 같은 경우에는 사용자 회전 환경설정이 변경될 수 있습니다. 기기의 자연스러운 회전(일반적으로 휴대전화 폼 팩터 기기의 경우 세로 모드)으로 돌아가는 경향이 있습니다.

  • 사용자가 회전 제안을 수락하면 회전 환경설정이 제안으로 변경됩니다.
  • 사용자가 잠금 화면 또는 런처를 포함하여 세로 모드로 강제된 앱으로 전환하면 회전 환경설정이 세로 모드로 변경됩니다.

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

화면 방향 동작
지정되지 않음, 사용자 자동 회전 및 회전 잠금에서 활동은 세로 모드 또는 가로 모드로 렌더링될 수 있으며 그 반대의 경우도 가능합니다. 세로 모드 및 가로 모드 레이아웃을 모두 지원할 것으로 예상됩니다.
userLandscape 자동 회전 및 회전 잠금에서는 활동이 가로 모드 또는 역가로 모드로 렌더링될 수 있습니다. 가로 모드 레이아웃만을 지원할 것으로 예상됩니다.
userPortrait 자동 회전 및 회전 잠금에서 활동은 세로 모드 또는 역세로 모드로 렌더링될 수 있습니다. 세로 모드 레이아웃만을 지원할 것으로 예상됩니다.
fullUser 자동 회전 및 회전 잠금에서 활동은 세로 모드 또는 가로 모드로 렌더링될 수 있으며 그 반대의 경우도 가능합니다. 세로 모드와 가로 모드 레이아웃을 모두 지원해야 합니다.

회전 잠금 사용자에게는 세로 모드(일반적으로 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에 위임하면 이러한 클래스가 더 이상 시스템 ClassLoader에 알려지지 않으므로 Android 9 이상에서 앱이 NoClassDefFoundError 오류와 함께 실패합니다. 향후 유사한 문제가 발생하지 않도록 하려면 앱은 일반적으로 시스템 ClassLoader에 직접 액세스하는 대신 앱 ClassLoader를 통해 클래스를 로드해야 합니다.

카메라 열거

Android 9 기기에서 실행되는 앱은 getCameraIdList()를 호출하여 사용 가능한 모든 카메라를 검색할 수 있습니다. 앱은 기기에 후면 카메라가 하나만 있거나 전면 카메라가 하나만 있다고 가정해서는 안 됩니다.

예를 들어 앱에 전면 카메라와 후면 카메라 간에 전환하는 버튼이 있는 경우 선택할 수 있는 전면 또는 후면 카메라가 두 대 이상일 수 있습니다. 카메라 목록을 살펴보고 각 카메라의 특성을 검사한 후 사용자에게 노출할 카메라를 결정해야 합니다.