동작 변경사항: 모든 앱

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를 실행하는 기기에서 백그라운드로 실행 중이면 시스템은 다음 제한사항을 앱에 적용합니다.

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

앱이 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을 파싱하면 '세계 협정시' 및 '그리니치 표준시'와 같은 문자열을 인식합니다.
      • 모든 언어에서 zzzz의 출력 값이 'UTC' 또는 'GMT+00:00'이라고 가정하면 앱에서 호환성 문제가 발생할 수 있습니다.
    • java.text.DateFormatSymbols.getZoneStrings()의 동작이 변경되었습니다.
      • SimpleDateFormat와 마찬가지로 UTC와 GMT의 이름이 이제 깁니다. 'UTC', 'Etc/UTC', 'Zulu'와 같은 UTC 시간대의 시간대 이름의 DST 변형은 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이 발생할 수 있습니다. 이 문제를 방지하려면 Android 7.0 (API 수준 24)부터 PLURALCURRENCYSTYLE 스타일의 통화 텍스트에 사용할 수 있는 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()를 호출하면 됩니다.

소켓에서 사용 가능한 바이트의 보고된 양

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

VPN에 대한 보다 상세한 네트워크 기능 보고

Android 8.1(API 수준 27) 이하에서 NetworkCapabilities 클래스는 VPN에 관한 제한된 정보(예: 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 폴더의 파일에 대한 직접 읽기 액세스가 허용되지 않습니다. 그 이유는 이러한 파일이 전혀 없는 일부 기기와의 일관성을 유지하기 위해서입니다.

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

이제 FLAG_ACTIVITY_NEW_TASK 요구사항이 적용됩니다.

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

화면 회전 변경사항

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

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

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

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

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

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

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

화면 방향 동작
미지정, 사용자 자동 회전 및 회전 잠금에서 Activity가 세로 또는 가로 (또는 그 반대로)로 렌더링될 수 있습니다. 세로 모드 및 가로 모드 레이아웃을 모두 지원할 것으로 예상됩니다.
사용자 환경 자동 회전 및 회전 잠금 모드에서 활동이 가로 모드 또는 가로 반전으로 렌더링될 수 있습니다. 가로 모드 레이아웃만을 지원할 것으로 예상됩니다.
사용자세로 자동 회전 및 회전 잠금에서 활동은 세로 모드 또는 반전 세로 모드로 렌더링될 수 있습니다. 세로 모드 레이아웃만을 지원할 것으로 예상됩니다.
전체 사용자 자동 회전 및 회전 잠금에서 Activity가 세로 또는 가로 (또는 그 반대로)로 렌더링될 수 있습니다. 세로 모드와 가로 모드 레이아웃을 모두 지원할 것으로 예상됩니다.

회전 잠금 사용자에게 세로 반전(보통 180도)으로 잠글 수 있는 옵션이 제공됩니다.
센서, 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()를 호출하여 사용 가능한 모든 카메라를 검색할 수 있습니다. 앱은 기기에 하나의 후면 카메라 또는 하나의 전면 카메라만 있다고 가정해서는 안 됩니다.

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