Android 17 플랫폼에는 앱에 영향을 줄 수 있는 동작 변경사항이 있습니다.
Android 17에서 실행될 때 모든 앱에 적용되는 동작 변경사항은 다음과 같습니다.
targetSdkVersion에 관계없이 이러한 변경사항을 적절히 지원해야 하는 경우 앱을 테스트한 후 필요에 따라 수정해야 합니다.
또한 Android 17을 타겟팅하는 앱에만 영향을 주는 동작 변경사항 목록 을 검토해야 합니다.
핵심 기능
Android 17 (API 수준 37)에는 Android 시스템의 다양한 핵심 기능을 수정하거나 확장하는 다음과 같은 변경사항이 포함되어 있습니다.
앱 메모리 제한
Android 17 introduces app memory limits based on the device's total RAM to create a more stable and deterministic environment for your apps and Android users. In Android 17, limits are set conservatively to establish system baselines, targeting extreme memory leaks and other outliers before they trigger system-wide instability resulting in UI stuttering, higher battery drain, and apps being killed. While we anticipate minimal impact on the vast majority of app sessions, we recommend the following memory best practices, including establishing a baseline for memory.
You can determine if your app session was impacted by calling
getDescription in ApplicationExitInfo; if your app was
affected, the exit reason will be REASON_OTHER and
the description will contain the string "MemoryLimiter:AnonSwap" along with
other information. You can also use trigger-based profiling with
TRIGGER_TYPE_ANOMALY to get heap dumps that are collected when the
memory limit is hit.
The Manage your app's memory documentation gives information to help you diagnose your app's memory issues and optimize its resource consumption.
Test your app's behavior under the memory constraints
You can use Android Debug Bridge (adb) to adjust or disable the
memory limits on any device that imposes them. The shell command am
provides three subcommands to adjust the memory limits. (These commands have
no effect on a device which does not impose memory limits.)
am memory-limiter ignore <uid>|none|allam memory-limiter manual <pid> <limit>|max|noneam memory-limiter status
ignoreInstructs the memory limiter to ignore some or all processes. Passing a UID (Android User ID) instructs the memory limiter to ignore enforcement on all processes associated with that UID. You can also pass
all(ignore all apps) ornone(do not ignore any apps). Passingnoneoverrides any previous calls toam memory-limiter ignore.If you instruct the memory limiter to ignore a UID, you can still apply a manual memory limit to a process within the app by calling
am memory-limiter manual.manualInstructs the system to impose a memory constraint on the process with the specified PID (Process ID). The memory constraint is specified as an integer number of MB; for example, passing
30specifies that the process is limited to 30 MB of memory. Passingmaxremoves all memory limits on that process. Passingnoneremoves any manual limits set on the process, restoring the system's default limit (if any).statusReports the current status of the memory limiter. The status includes the memory limits imposed on visible and non-visible processes.
개인 정보 보호
Android 17에는 사용자 개인 정보 보호를 개선하기 위한 다음과 같은 변경사항이 포함되어 있습니다.
SMS OTP 보호
Android 17부터 Android는 일회용 비밀번호 (OTP)가 포함된 SMS 메시지에 대한 보호를 확대합니다.
이전 버전의 Android에서는 이 보호가 주로 SMS Retriever 형식에 중점을 두었습니다. SMS Retriever 해시가 포함된 메시지 전송은 대부분의 앱에서 3시간 동안 지연되었습니다. 그러나 특정 앱 (예: 기본 SMS 핸들러)은 지연에서 제외되었으며 해시를 소유한 앱도 제외되었습니다.
Android 17부터는 WebOTP 형식 메시지에도 보호가 적용됩니다. 앱에 SMS 메시지를 읽을 권한이 있지만 도메인 확인에 따라 WebOTP 메시지의 수신자가 아닌 경우 메시지를 받은 후 3시간이 지나야 앱에서 메시지에 액세스할 수 있습니다. 이번 변경사항은 메시지에 언급된 도메인과 연결된 앱만 프로그래매틱 방식으로 인증 코드를 읽을 수 있도록 하여 사용자 보안을 개선하기 위한 것입니다.
이 3시간 지연 동안 SMS_RECEIVED_ACTION 브로드캐스트가
보류되고 SMS 제공업체 데이터베이스 쿼리가 필터링됩니다. 지연 후 이러한 앱에서 SMS 메시지를 사용할 수 있습니다. 이번 변경사항은 대상 API 수준과 관계없이
모든 앱에 적용됩니다.
기본 SMS 어시스턴트 앱, 연결된 기기 도우미 앱 등과 같은 특정 앱은 이 지연에서 제외됩니다. OTP 추출을 위해 SMS 메시지 읽기에 의존하는 모든 앱은 지속적인 기능을 보장하기 위해 SMS Retriever 또는 SMS User Consent API를 사용하도록 전환해야 합니다.
보안
Android 17에는 기기 및 앱 보안을 개선하기 위한 다음과 같은 변경사항이 포함되어 있습니다.
usesClearTraffic 지원 중단 계획
향후 출시에서는 usesCleartextTraffic 요소를 지원 중단할 계획입니다.
암호화되지 않은 (HTTP) 연결을 만들어야 하는 앱은 네트워크 보안 구성 파일을 사용하도록 이전해야 합니다. 이 파일을 사용하면 앱이 일반 텍스트 연결을 만들어야 하는 도메인을 지정할 수 있습니다.
네트워크 보안 구성 파일은 API 수준 24 이상에서만 지원됩니다. 앱의 최소 API 수준이 24 미만인 경우 다음 두 가지를 모두 실행해야 합니다.
usesCleartextTraffic속성을true으로 설정- 네트워크 구성 파일 사용
앱의 최소 API 수준이 24 이상이면 네트워크 구성 파일을 사용할 수 있으며 usesCleartextTraffic를 설정하지 않아도 됩니다.
암시적 URI 부여 제한
현재 앱이 작업이 있는 URI로 인텐트를 실행하면
ACTION_SEND, ACTION_SEND_MULTIPLE 또는
ACTION_IMAGE_CAPTURE 시스템은 자동으로 대상 앱에 읽기 및
쓰기 URI 권한을 부여합니다. Android 18부터 시스템은
이러한 권한을 자동으로 부여하지 않습니다. 따라서 앱은 시스템에 의존하여 권한을 부여하는 대신 관련 URI 권한을 명시적으로 부여하는 것이 좋습니다.
앱에서 이러한 인텐트의 사용을 감지하려면 StrictMode와 함께
detectImplicitUriPermissionGrant()를 사용하여 위반을 트리거합니다.
Kotlin
val policy = StrictMode.VmPolicy.Builder() .detectImplicitUriPermissionGrant() .penaltyLog() .build() StrictMode.setVmPolicy(policy)
Java
StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder() .detectImplicitUriPermissionGrant() .penaltyLog() .build(); StrictMode.setVmPolicy(policy);
또는 시스템이 암시적으로 권한을 설정할 때 표시되는 Please set the grant explicitly in the app 메시지가 포함된 로깅된 예외를 모니터링할 수 있습니다. 다음 adb 명령어를 사용하여 이러한 로그를 모니터링할 수 있습니다.
adb logcat | grep "Please set the grant explicitly in the app"
필요한 권한을 명시적으로 부여하려면 ACTION_SEND 및
ACTION_SEND_MULTIPLE 인텐트에
FLAG_GRANT_READ_URI_PERMISSION 플래그를 추가합니다.
Kotlin
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
Java
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
ACTION_IMAGE_CAPTURE 인텐트에 FLAG_GRANT_READ_URI_PERMISSION 및
FLAG_GRANT_WRITE_URI_PERMISSION 플래그를 모두 포함합니다.
Kotlin
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
자바
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
앱별 키 저장소 한도
Android 키 저장소는 기기의 모든 앱을 위한 공유 리소스이므로 앱은 Android 키 저장소에 과도한 수의 키를 만들지 않아야 합니다. Android 17부터 시스템은 앱이 소유할 수 있는 키 수에 제한을 적용합니다. 제한은 Android 17 (API 수준 37) 이상을 타겟팅하는 비시스템 앱의 경우 50,000개의 키이고 다른 모든 앱의 경우 200,000개의 키입니다. 시스템 앱은 타겟팅하는 API 수준과 관계없이 200,000개의 키로 제한됩니다.
앱이 제한을 초과하는 키를 만들려고 하면 생성에 실패합니다.
KeyStoreException 예외의 메시지 문자열에는 키 제한에 관한 정보가 포함되어 있습니다. 앱이 예외에서 getNumericErrorCode()를 호출하는 경우 반환 값은 앱이 타겟팅하는 API 수준에 따라 다릅니다.
- Android 17 (API 수준 37) 이상을 타겟팅하는 앱:
getNumericErrorCode()는 새ERROR_TOO_MANY_KEYS값을 반환합니다. - 다른 모든 앱:
getNumericErrorCode()는ERROR_INCORRECT_USAGE를 반환합니다.
교차 프로필 루프백 트래픽 차단
Android 17부터는 교차 프로필 루프백 트래픽이 기본적으로 더 이상 허용되지 않습니다. 동일한 프로필 내의 루프백 트래픽은 영향을 받지 않습니다. 이 변경사항은 앱이 타겟팅하는 API 수준과 관계없이 Android 17 이상에서 실행되는 모든 앱에 적용됩니다.
사용자 환경 및 시스템 UI
Android 17에는 더 일관되고 직관적인 사용자 환경을 만들기 위한 다음과 같은 변경사항이 포함되어 있습니다.
회전 후 기본 IME 공개 상태 복원
Android 17부터 기기의 구성이 변경되고 (예: 회전을 통해) 앱 자체에서 이를 처리하지 않으면 이전 IME 가시성이 복원되지 않습니다.
앱이 처리하지 않는 구성 변경이 발생하고 변경 후 앱에 키보드가 표시되어야 하는 경우 이를 명시적으로 요청해야 합니다. 다음 방법 중 하나로 요청할 수 있습니다.
android:windowSoftInputMode속성을stateAlwaysVisible으로 설정합니다.- 활동의
onCreate()메서드에서 프로그래매틱 방식으로 소프트 키보드를 요청하거나onConfigurationChanged()메서드를 추가합니다.
수동 입력
Android 17에는 앱이 키보드 및 터치패드와 같은 수동 입력 기기와 상호작용하는 방식에 영향을 주는 다음과 같은 변경사항이 포함되어 있습니다.
터치패드는 포인터 캡처 중에 기본적으로 상대 이벤트를 전달함
Android 17부터 앱이
View.requestPointerCapture()를 사용하여 포인터 캡처를 요청하고 사용자가 터치패드를 사용하는 경우 시스템은
사용자의 터치에서 포인터 이동 및 스크롤 동작을 인식하고
캡처된 마우스의 포인터 및 스크롤 휠 이동과 동일한 방식으로 앱에
보고합니다. 대부분의 경우 이렇게 하면 캡처된 마우스를 지원하는 앱에서 터치패드에 대한 특수 처리 로직을 추가할 필요가 없습니다. 자세한 내용은
View.POINTER_CAPTURE_MODE_RELATIVE 문서를 참고하세요.
이전에는 시스템이 터치패드의 동작을 인식하려고 시도하지 않고 대신 터치스크린 터치와 유사한 형식으로 원시 절대 손가락 위치를 앱에 전달했습니다. 앱에 여전히 이 절대 데이터가 필요한 경우 이
대신 새 View.requestPointerCapture(int) 메서드를
View.POINTER_CAPTURE_MODE_ABSOLUTE 호출해야 합니다.
미디어
Android 17에는 미디어 동작에 다음과 같은 변경사항이 포함되어 있습니다.
백그라운드 오디오 강화
Android 17부터 오디오 프레임워크는 오디오 재생, 오디오 포커스 요청, 볼륨 변경 API를 비롯한 백그라운드 오디오 상호작용에 제한을 적용하여 이러한 변경사항이 사용자에 의해 의도적으로 시작되도록 합니다.
앱이 유효한 수명 주기에 있지 않은 동안 앱이 오디오 API를 호출하려고 하면 오디오 재생 및 볼륨 변경 API가 예외를 발생시키거나 실패 메시지를 제공하지 않고 자동으로 실패합니다. 오디오 포커스 API는 결과 코드 AUDIOFOCUS_REQUEST_FAILED로 실패합니다.
완화 전략을 비롯한 자세한 내용은 백그라운드 오디오 강화을 참고하세요.
연결
Android 17에는 기기 연결을 개선하기 위한 다음과 같은 변경사항이 포함되어 있습니다.
블루투스 페어링 손실 시 자동 재페어링
Android 17에서는 블루투스 결합 손실을 자동으로 해결하도록 설계된 시스템 수준의 개선사항인 자율 재페어링이 도입되었습니다.
이전에는 결합이 손실되면 사용자가 설정으로 직접 이동하여 주변 기기를 페어링 해제한 후 다시 페어링해야 했습니다. 이 기능은 Android 16의 보안 개선사항을 기반으로 하며, 사용자가 설정으로 직접 이동하여 주변 기기를 페어링 해제하고 다시 페어링하지 않아도 시스템이 백그라운드에서 결합을 다시 설정할 수 있도록 합니다.
대부분의 앱에는 코드 변경이 필요하지 않지만 개발자는 블루투스 스택의 다음과 같은 동작 변경사항을 알고 있어야 합니다.
- 새 페어링 컨텍스트: 이제
ACTION_PAIRING_REQUEST에 앱이 표준 페어링 요청과 자율 시스템 시작 재페어링 시도를 구분할 수 있는EXTRA_PAIRING_CONTEXT추가 기능이 포함됩니다. - 조건부 키 업데이트: 기존 보안 키는 재페어링이 성공하고 새 연결이 이전 결합의 보안 수준을 충족하거나 초과하는 경우에만 대체됩니다.
- 수정된 인텐트 타이밍: 이제
ACTION_KEY_MISSING인텐트는 자율 재페어링 시도가 실패하는 경우에만 브로드캐스트됩니다. 이렇게 하면 시스템이 백그라운드에서 결합을 성공적으로 복구하는 경우 앱에서 불필요한 오류 처리가 줄어듭니다. - 사용자 알림: 시스템은 새로운 UI 알림 및 대화상자를 통해 재페어링을 관리합니다. 사용자에게 재페어링 시도를 확인하라는 메시지가 표시되어 재연결을 알 수 있습니다.
주변 기기 제조업체와 컴패니언 앱 개발자는 하드웨어와 앱이 결합 전환을 정상적으로 처리하는지 확인해야 합니다. 이 동작을 테스트하려면 다음 방법 중 하나를 사용하여 원격 결합 손실을 시뮬레이션하세요.
- 주변 기기에서 결합 정보를 수동으로 삭제합니다.
- 설정 > 연결된 기기에서 기기를 수동으로 페어링 해제합니다.