동작 변경사항: 모든 앱

Android 17 플랫폼에는 앱에 영향을 줄 수 있는 동작 변경사항이 있습니다. Android 17에서 실행될 때 모든 앱에 적용되는 동작 변경사항은 다음과 같습니다. targetSdkVersion에 관계없이 이러한 변경사항을 적절히 지원해야 하는 경우 앱을 테스트한 후 필요에 따라 수정해야 합니다.

또한 Android 17을 타겟팅하는 앱에만 영향을 주는 동작 변경사항 목록 을 검토해야 합니다.

핵심 기능

Android 17 (API 수준 37)에는 Android 시스템의 다양한 핵심 기능을 수정하거나 확장하는 다음과 같은 변경사항이 포함되어 있습니다.

앱 메모리 제한

Android 17에서는 기기의 총 RAM에 기반한 앱 메모리 제한을 도입하여 앱과 Android 사용자에게 더 안정적이고 결정론적인 환경을 제공합니다. 이러한 제한은 시스템 전체의 불안정성을 유발하여 UI 끊김 현상, 배터리 소모 증가, 앱 종료를 초래하기 전에 메모리 누수 및 기타 이상치에 중점을 둡니다. 대부분의 앱 세션에 미치는 영향은 최소화될 것으로 예상되지만 메모리 기준 설정 등 다음과 같은 메모리 권장사항을 따르는 것이 좋습니다.

`ApplicationExitInfo`에서 getDescription을 호출하여 앱 세션이 영향을 받았는지 확인할 수 있습니다. 앱이 영향을 받은 경우 종료 이유는 REASON_OTHER이고 설명에는 다른 정보와 함께 문자열 "MemoryLimiter:AnonSwap"이 포함됩니다. 또한 트리거 기반 프로파일링을 사용하여 TRIGGER_TYPE_ANOMALY 메모리 한도에 도달했을 때 수집되는 힙 덤프를 가져올 수 있습니다.

앱 메모리 관리 문서에서는 앱의 메모리 문제를 진단하고 리소스 소비를 최적화하는 데 도움이 되는 정보를 제공합니다.

메모리 제약 조건에서 앱 동작 테스트

Android 디버그 브리지 (adb)를 사용하여 메모리 제한을 적용하는 모든 기기에서 메모리 제한을 조정하거나 사용 중지할 수 있습니다. 셸 명령어 am은 메모리 제한을 조정하는 세 가지 하위 명령어를 제공합니다. (이러한 명령어는 메모리 제한을 적용하지 않는 기기에는 영향을 미치지 않습니다.)

  • am memory-limiter ignore <uid>|none|all
  • am memory-limiter manual <pid> <limit>|max|none
  • am memory-limiter status
ignore

메모리 제한 도구에 일부 또는 모든 프로세스를 무시하도록 지시합니다. UID (Android 사용자 ID)를 전달하면 메모리 제한 도구에 해당 UID와 연결된 모든 프로세스에 대한 적용을 무시하도록 지시합니다. all (모든 앱 무시) 또는 none(앱 무시 안 함)을 전달할 수도 있습니다. none을 전달하면 이전의 am memory-limiter ignore 호출이 재정의됩니다.

메모리 제한 도구에 UID를 무시하도록 지시하더라도 am memory-limiter manual을 호출하여 앱 내 프로세스에 수동 메모리 제한을 적용할 수 있습니다.

manual

시스템에 지정된 PID (프로세스 ID)가 있는 프로세스에 메모리 제약 조건을 적용하도록 지시합니다. 메모리 제약 조건은 정수 MB 수로 지정됩니다. 예를 들어 30을 전달하면 프로세스가 30MB의 메모리로 제한됩니다. max를 전달하면 해당 프로세스의 모든 메모리 제한이 삭제됩니다. none을 전달하면 프로세스에 설정된 수동 제한이 삭제되고 시스템의 기본 제한 (있는 경우)이 복원됩니다.

status

메모리 제한 도구의 현재 상태를 보고합니다. 상태에는 표시되는 프로세스와 표시되지 않는 프로세스에 적용되는 메모리 제한이 포함됩니다.

개인 정보 보호

Android 17에는 사용자 개인 정보 보호를 개선하기 위한 다음과 같은 변경사항이 포함되어 있습니다.

SMS OTP 보호

从 Android 17 开始,Android 将扩大对包含一次性密码 (OTP) 的短信的保护范围。

在之前的 Android 版本中,此保护主要侧重于 SMS Retriever 格式。对于大多数应用,包含 SMS Retriever 哈希的消息的递送延迟了 3 小时。不过,某些应用(例如默认短信处理程序)不受此延迟的影响,拥有哈希的应用也不受此延迟的影响。

从 Android 17 开始,此保护也适用于 WebOTP 格式的消息。如果应用有权读取短信,但不是 WebOTP 消息的预期接收者(由网域验证确定),则该应用在收到消息后 3 小时内无法访问该消息。此变更旨在提高用户安全性,确保只有与消息中提及的网域关联的应用才能以编程方式读取验证码。

在这 3 小时的延迟期间,系统会保留 SMS_RECEIVED_ACTION 广播,并过滤 短信提供商 数据库查询。延迟结束后,这些应用即可使用短信。此变更适用于 所有应用,无论其目标 API 级别如何。

某些应用(例如默认短信助理应用、关联设备配套应用等)不受此延迟的影响。所有依赖于读取短信 来提取 OTP 的应用都应过渡到使用 SMS RetrieverSMS User Consent API,以确保功能持续可用。

보안

Android 17에는 기기 및 앱 보안을 개선하기 위한 다음과 같은 변경사항이 포함되어 있습니다.

usesClearTraffic 지원 중단 계획

In a future release, we plan to deprecate the usesCleartextTraffic element. Apps that need to make unencrypted (HTTP) connections should migrate to using a network security configuration file, which lets you specify which domains your app needs to make cleartext connections to.

Be aware that network security configuration files are only supported on API levels 24 and higher. If your app has a minimum API level lower than 24, you should do both of the following:

  • Set the usesCleartextTraffic attribute to true
  • Use a network configuration file

If your app's minimum API level is 24 or higher, you can use a network configuration file and you don't need to set 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_SENDACTION_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_PERMISSIONFLAG_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
  • 在 activity 的 onCreate() 方法中以编程方式请求显示软键盘,或添加 onConfigurationChanged() 方法。

수동 입력

Android 17에는 앱이 키보드 및 터치패드와 같은 수동 입력 기기와 상호작용하는 방식에 영향을 주는 다음과 같은 변경사항이 포함되어 있습니다.

터치패드는 포인터 캡처 중에 기본적으로 상대 이벤트를 전달함

Beginning with Android 17, if an app requests pointer capture using View.requestPointerCapture() and the user uses a touchpad, the system recognizes pointer movement and scrolling gestures from the user's touches and reports them to the app in the same way as pointer and scroll wheel movements from a captured mouse. In most cases, this removes the need for apps that support captured mice to add special handling logic for touchpads. For more details, see the documentation for View.POINTER_CAPTURE_MODE_RELATIVE.

Previously, the system did not attempt to recognize gestures from the touchpad, and instead delivered the raw, absolute finger locations to the app in a similar format to touchscreen touches. If an app still requires this absolute data, it should call the new View.requestPointerCapture(int) method with View.POINTER_CAPTURE_MODE_ABSOLUTE instead.

미디어

Android 17에는 미디어 동작에 다음과 같은 변경사항이 포함되어 있습니다.

백그라운드 오디오 강화

Beginning with Android 17, the audio framework enforces restrictions on background audio interactions including audio playback, audio focus requests, and volume change APIs to ensure that these changes are started intentionally by the user.

If the app tries to call audio APIs while the app is not in a valid lifecycle, the audio playback and volume change APIs fail silently without throwing an exception or providing a failure message. The audio focus API fails with the result code AUDIOFOCUS_REQUEST_FAILED.

For more information, including mitigation strategies, see Background audio hardening.

연결

Android 17에는 기기 연결을 개선하기 위한 다음과 같은 변경사항이 포함되어 있습니다.

블루투스 페어링 손실 시 자동 재페어링

Android 17 introduces autonomous re-pairing, a system-level enhancement designed to automatically resolve Bluetooth bond loss.

Previously, if a bond was lost, users had to manually navigate to Settings to unpair and then re-pair the peripheral. This feature builds upon the security improvement of Android 16 by allowing the system to re-establish bonds in the background without requiring users to manually navigate to Settings to unpair and re-pair peripherals.

While most apps will not require code changes, developers should be aware of the following behavior changes in Bluetooth stack:

  • New pairing context: The ACTION_PAIRING_REQUEST now includes the EXTRA_PAIRING_CONTEXT extra which allows apps to distinguish between a standard pairing request and an autonomous system-initiated re-pairing attempt.
  • Conditional key updates: Existing security keys will only be replaced if the re-pairing is successful and new connection meets or exceeds the security level of the previous bond.
  • Modified intent timing: The ACTION_KEY_MISSING intent is now broadcast only if the autonomous re-pairing attempt fails. This reduces unnecessary error handling in the app if the system successfully recovers the bond in the background.
  • User notification: The system manages re-pairing via new UI notifications and dialogs. Users will be prompted to confirm the re-pairing attempt to ensure they are aware of the reconnection.

Peripheral device manufacturers and companion app developers should verify that hardware and app gracefully handle bond transitions. To test this behavior, simulate a remote bond loss using either of the following methods:

  • Manually remove the bond information from the peripheral device
  • Manually unpair the device in: Settings > Connected devices