대형 화면 호환 모드

Android에서는 방향 또는 크기 조절 가능 여부를 선언하는 앱을 위해 호환성 모드가 활성화됩니다. 호환성 모드를 사용하면 대형 화면 기기에서 허용되는 앱 동작이 보장되지만 사용성이 최적화되지는 않습니다.

앱별 재정의를 사용하면 기기 OEM(Original Equipment Manufacturer)이 앱 동작을 변경하여 사용자 환경을 개선하거나 대형 화면에서 앱이 손상되는 것을 방지할 수 있습니다.

일반적인 호환성 문제

앱의 호환성 문제가 가장 자주 발생하는 이유는 앱 방향 제한, 크기 조절 가능 여부, 가로세로 비율 제한, 잘못된 카메라 미리보기 방향 처리, API 오용 때문입니다.

레터박스

레터박스는 앱을 화면의 중앙에 배치하거나 대형 화면에서는 쉽게 액세스할 수 있도록 한쪽 또는 다른 쪽에 배치합니다. 매트(단색 막대 또는 블러 처리된 배경화면)는 앱의 양 측면 또는 상단과 하단을 따라 사용되지 않는 디스플레이 영역을 채웁니다.

레터박스는 대형 화면 기기에서 흔히 발생합니다. 일반적으로 기기 디스플레이의 크기와 가로세로 비율이 대부분의 앱이 설계된 표준 휴대전화의 크기 및 가로세로 비율과 다르기 때문입니다.

그림 1. 가로 모드 태블릿 및 폴더블에서 레터박스 처리된 세로 모드 방향으로 제한된 앱

문제

앱이 모든 디스플레이 구성을 지원하는 것은 아닙니다. 앱의 방향이나 가로세로 비율이 고정되어 있거나 앱의 크기를 조절할 수 없기 때문입니다.

앱 방향과 크기 조절 가능 여부를 제어하는 구성 설정은 다음과 같습니다.

  • screenOrientation: 앱의 고정된 방향을 지정합니다. 앱은 런타임에 Activity#setRequestedOrientation()을 사용하여 방향을 설정할 수도 있습니다.
  • resizeableActivity: 시스템에서 다양한 크기의 창에 맞게 앱 크기를 조절할 수 있는지를 나타냅니다. Android 11(API 수준 30) 및 이전 버전에서는 앱이 멀티 윈도우 모드를 지원하는지 지정합니다. Android 12(API 수준 31) 및 이후 버전에서는 앱이 작은 화면(sw 600dp 미만)에서 멀티 윈도우 모드를 지원하는지 지정합니다. Android 12 및 이후 버전에서는 앱이 이 설정과 관계없이 대형 화면(sw 600dp 이상)에서 멀티 윈도우 모드를 지원합니다.
  • maxAspectRatio: 앱에서 지원하는 최대 가로세로 비율을 지정합니다. resizeableActivity가 false로 설정된 앱만 maxAspectRatio를 설정할 수 있습니다.
  • minAspectRatio: 앱에서 지원하는 최소 가로세로 비율을 지정합니다. resizeableActivity가 false로 설정된 앱만 minAspectRatio를 설정할 수 있습니다.

최적화

앱은 모든 기기와 멀티 윈도우 모드 디스플레이 방향 및 크기를 지원해야 합니다. 앱 레이아웃 및 앱 매니페스트 파일에서 모든 방향 및 고정된 가로세로 비율 제한을 삭제하세요. 자세한 내용은 다양한 화면 크기 지원을 참고하세요.

호환성 해결 방법

방향이나 가로세로 비율이 고정된 앱이 창 크기나 방향을 직접 지원하지 않는 창에서 실행되는 경우 Android는 연속성을 유지하기 위해 앱을 레터박스 처리합니다.

Android 12(API 수준 31)부터 12L(API 수준 32)까지 플랫폼에서는 레터박스 앱에 다양한 개선사항을 적용합니다. 기기 제조업체에서 UI 개선사항을 구현하므로 이러한 개선사항의 이점을 얻기 위해 앱을 추가로 개발하지 않아도 됩니다.

Android 12(API 수준 31)에서는 기기 제조업체에서 구성할 수 있는 다음과 같은 미학적 개선사항을 도입합니다.

  • 둥근 모서리: 앱 창의 모서리에 더 세련된 모양이 적용됩니다.
  • 시스템 표시줄 투명도: 앱을 오버레이하는 상태 및 탐색 메뉴는 반투명해서 메뉴의 아이콘이 레터박스 배경 위에 항상 표시됩니다.
  • 구성 가능한 가로세로 비율: 앱의 가로세로 비율을 조정하여 앱 모양을 개선할 수 있습니다.

그림 2. UI 개선사항이 있는 레터박스 처리된 앱

12L(API 수준 32)에서는 다음과 같은 기능 개선사항을 추가합니다.

  • 구성 가능한 배치: 대형 화면의 경우 기기 제조업체가 편리한 상호작용을 위해 디스플레이의 왼쪽이나 오른쪽에 앱을 배치할 수 있습니다.
  • 새롭게 디자인된 다시 시작 버튼: 기기 제조업체는 사용자가 더 잘 인식할 수 있도록 크기 호환성 모드의 다시 시작 버튼을 새롭게 디자인할 수 있습니다.

Android 13(API 수준 33)에서는 레터박스 처리된 앱을 화면에 배치하거나 화면 분할 모드에 레터박스를 포함하는 방법에 관한 사용자 교육 대화상자를 추가합니다.

그림 3. 사용자 교육 대화상자가 있는 레터박스 처리된 앱

크기 호환성 모드

크기 호환성 모드는 다시 시작 컨트롤이 포함된 레터박스입니다. 컨트롤을 사용하면 사용자가 앱을 다시 시작하고 디스플레이를 다시 그릴 수 있습니다. Android에서는 크기를 조절할 수 없는 것으로 확인된 앱을 위해 크기 호환성 모드를 호출합니다. 활동이 크기가 호환되지 않는 디스플레이 컨테이너로 이동하면 시스템에서 앱의 크기를 조정하여 하나 이상의 치수에서 기기 디스플레이를 채울 수 있습니다.

크기 호환성 모드를 트리거할 수 있는 기기 설정 변경사항은 다음과 같습니다.

  • 기기 회전
  • 폴더블 기기 접기 또는 펼치기
  • 전체 화면 디스플레이 모드와 화면 분할 디스플레이 모드 간 변경

문제

크기 호환성 모드는 일반적으로 방향 또는 가로세로 비율이 제한되고 크기를 조절할 수 없도록 구성(또는 시스템에서 결정)되는 활동에 적용됩니다.

다음 기준 중 하나라도 충족하는 경우 앱은 크기를 조절할 수 있는 것으로 간주되며 크기 호환성 모드로 전환되지 않습니다.

앱이 어떤 조건도 충족하지 않으면 크기를 조절할 수 없는 것으로 간주되어 크기 호환성 모드로 전환될 수 있습니다.

최적화

앱은 모든 디스플레이 크기를 지원해야 합니다. 앱 매니페스트에서 <activity> 또는 <application> 요소의 android:resizeableActivity 속성을 true로 설정하여 앱의 크기를 조절할 수 있도록 합니다. 앱의 반응형/적응형 레이아웃을 설계합니다. 자세한 내용은 다양한 화면 크기 지원멀티 윈도우 지원을 참고하세요.

호환성 해결 방법

Android는 시스템이 앱의 크기를 조정하여 하나 이상의 크기에서 디스플레이 창을 채움으로써 레터박스 처리된 앱의 디스플레이를 개선할 수 있다고 판단하는 경우 앱을 크기 호환성 모드로 전환합니다. 시스템은 앱 프로세스를 다시 만들어 활동을 다시 만들고 디스플레이를 다시 그리는 다시 시작 컨트롤을 표시합니다. 프로세스 및 스레드 개요도 참고하세요.

깜박이는 루프

앱이 모든 디스플레이 방향을 지원하지 않는 경우 구성 변경 시 반복적으로 새로운 방향을 요청하므로 디스플레이가 깜박이거나 앱이 계속 회전하게 되는 무한 루프가 생성될 수 있습니다.

문제

Android 12(API 수준 31) 및 이후 버전에서는 기기 제조업체가 앱에서 지정한 방향 제한을 무시하고 대신 호환성 모드를 구동하는 제한사항을 사용하도록 기기를 구성할 수 있습니다. 예를 들어, 폴더블 기기는 활동이 기기의 가로 모드 태블릿 크기 내부 화면에 표시될 때 활동의 android:screenOrientation="portrait" 설정을 무시할 수 있습니다.

앱의 방향 제한이 무시되면 앱은 Activity#setRequestedOrientation()을 호출하여 프로그래매틱 방식으로 방향을 설정할 수 있습니다. 이 호출은 앱이 구성 변경을 처리하지 않는 경우 앱 다시 시작을 트리거합니다(구성 변경 처리 참고). 다시 시작하면 앱의 방향 제한이 다시 무시되고 앱에서 setRequestedOrientation() 호출을 반복하며 호출이 앱 다시 시작을 트리거하는 등 자체 영구 루프가 계속됩니다.

기기 화면의 자연스러운 방향(Android에서 결정한 일반적인 방향)이 가로 모드일 때도 이 문제가 발생할 수 있습니다(즉, 기기가 가로 모드의 가로세로 비율일 때 Display#getRotation()을 호출하면 Surface.ROTATION_0이 반환됨). 지금까지 앱은 Display.getRotation() = Surface.ROTATION_0이 기기가 세로 모드 방향임을 의미한다고 가정했지만 항상 그런 것은 아닙니다(예: Pixel Fold 내부 화면 및 일부 태블릿).

Pixel Fold 내부 디스플레이에서 가로 모드 방향의 앱은 화면 회전을 확인하고 ROTATION_0 값을 수신하여 자연스러운 방향이 세로 모드 방향이라고 가정한 후 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)을 호출할 수 있습니다. 앱이 다시 시작된 후(가로 모드 방향으로) 화면 회전을 다시 확인하고 ROTATION_0 값을 수신하고 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)을 호출하는 등의 작업이 무한 루프로 실행될 수 있습니다.

최적화

앱은 다음 작업을 실행해서는 안 됩니다.

  • 처리되지 않은 구성 변경으로 인해 방향 요청이 예기치 않게 트리거될 수 있으므로 활동 onCreate() 메서드에서 Activity#setRequestedOrientation()으로 기본 방향을 설정합니다.
  • 기기의 자연스러운 방향(ROTATION_0)이 세로 모드라고 가정합니다.
  • Display#getRotation(), FoldingFeature의 존재 또는 지원 중단된 API와 같이 현재 창 크기와 관련 없는 신호를 기반으로 방향을 설정합니다(아래 참고).

호환성 해결 방법

Android는 다음과 같은 상황에서 Activity#setRequestedOrientation() 호출을 무시합니다.

카메라 미리보기

카메라 앱의 카메라 미리보기(또는 뷰파인더)는 태블릿, 노트북, 폴더블 디스플레이에서 잘못 정렬되거나 왜곡될 수 있습니다.

문제

Android 호환성 정의에서는 카메라 이미지 센서가 '카메라의 긴 쪽이 화면의 긴 쪽과 정렬되도록 방향을 설정해야 한다(MUST)'고 명시합니다.

앱은 기기 방향과 카메라 센서 방향이 세로 모드라고 가정하는 경우가 많으며 이는 표준 휴대전화에서는 합리적인 가정입니다. 하지만 태블릿 및 노트북과 카메라 센서의 자연스러운 방향은 가로 모드일 수 있습니다. 또한 폴더블과 같은 새로운 폼 팩터에는 여러 자연스러운 방향과 다양한 방향의 여러 카메라 센서가 있을 수 있습니다.

앱에서 예상하지 못한 카메라 방향으로 활동을 시작하거나 폴더블의 다른 카메라 또는 기기 화면 간에 전환하면 카메라 미리보기가 잘못 정렬되거나 왜곡될 수 있습니다.

최적화

카메라 앱은 기기 방향과 카메라 센서 방향을 제대로 식별하고 관리하여 올바르게 정렬되고 조정된 카메라 미리보기를 표시해야 합니다. 앱은 기기 회전, 센서 회전, 화면 또는 창 가로세로 비율을 계산한 후 결과를 카메라 미리보기에 적용해야 합니다. 자세한 내용은 카메라 미리보기카메라 뷰파인더 소개를 참고하세요.

호환성 해결 방법

Display#getRotation()Surface.ROTATION_0을 반환하면 기기는 자연스러운 방향입니다. 시스템은 기기의 자연스러운 방향에서 CameraCharacteristics.SENSOR_ORIENTATION을 계산합니다. Android에서는 세로 모드로 제한된 앱의 세로 모드 창을 기기의 자연스러운 방향(대부분의 앱에서 예상하는 방향)에 맞춥니다. 또한 센서 방향이 가로 모드이고 카메라 미리보기가 세로 모드면 카메라 센서 이미지를 자릅니다. 구체적인 해결 방법은 다음과 같습니다.

  • 세로 모드로 제한된 앱의 카메라 미리보기 강제 회전: 세로 모드 방향으로 제한된 앱은 기기의 자연스러운 방향 및 카메라 센서 방향이 세로 모드일 것으로 예상합니다. 그러나 Android 12(API 수준 31) 및 이후 버전에서는 기기 제조업체가 방향 사양을 무시하면 앱이 여러 기기 방향으로 실행될 수 있습니다.

    세로 모드 제한 앱이 카메라에 연결되면 Android에서 앱을 강제로 회전시켜 앱 세로 모드 창을 기기의 자연스러운 방향에 맞춥니다.

    Pixel Tablet에서 앱 세로 모드 창은 기기의 자연스러운 방향에 맞게 전체 화면 세로 모드로 회전합니다. 앱은 강제 회전 후 전체 화면을 차지합니다.

    Pixel Fold의 내부 화면에서는 펼쳐진 자연스러운 방향에 맞게 세로 모드 전용 활동이 가로 모드로 회전합니다. 앱은 강제 회전 후 레터박스 처리됩니다.

  • 내부 전면 카메라 자르기: Pixel Fold의 내부 전면 카메라 센서는 가로 모드 방향입니다. Android는 Pixel Fold 내부 디스플레이에서 카메라 미리보기를 강제로 회전하는 것 외에도 내부 전면(가로 모드) 카메라 시야를 잘라 센서가 기기 방향과 반대되는 뷰를 캡처하도록 합니다.

  • 카메라 미리보기 강제 새로고침: 시스템은 강제 회전 후 카메라 미리보기가 제대로 표시되는지 확인하기 위해 활동 메서드 onStop()onStart()(기본값) 또는 onPause()onResume()(OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE 앱별 재정의로 적용됨)을 순환합니다.

  • 가로세로 비율 조정: 시스템은 강제로 회전된 카메라 미리보기의 가로세로 비율을 더 높은 최소 가로세로 비율로 동적으로 변경하여 카메라 미리보기를 적절하게 조정합니다.

앱 개발자는 앱이 카메라 미리보기를 올바르게 처리하는 경우 이러한 해결 방법을 재정의할 수 있습니다. 아래 앱별 재정의를 참고하세요.

일반적으로 오용되는 API

Android에서 멀티 윈도우 모드와 같은 기능과 폴더블과 같은 기기를 추가로 지원함에 따라 기존 API는 지원 중단되고 모든 디스플레이 크기와 기기 폼 팩터에서 작동하는 최신 API로 대체되었습니다. 하지만 지원 중단된 API는 이전 버전과의 호환성을 위해 계속 사용할 수 있습니다.

일부 View API는 개발자가 잘 이해하지 못할 수 있는 특수한 목적으로 설계되었습니다.

문제

개발자가 지원 중단된 Display API를 계속 사용하면서 API가 기기 디스플레이 영역 경계 대신 앱 경계를 반환한다고 잘못 가정합니다. 또는 개발자가 특수 목적의 View API를 실수로 사용하여 일반 디스플레이 측정항목을 가져옵니다. 그 결과 앱 창의 크기 조절 이벤트 후 UI 요소의 위치를 변경할 때 계산이 잘못되어 레이아웃 문제가 발생합니다.

지원 중단되고 일반적으로 오용되는 Display API:

자세한 내용은 멀티 윈도우 지원을 참고하세요.

오용되는 View API:

최적화

UI 요소를 배치하는 데 실제 디스플레이 크기를 사용하지 마세요. 다음 WindowManager API를 포함하여 WindowMetrics에 기반한 API로 앱을 이전합니다.

호환성 해결 방법

두 재정의는 지원 중단된 Display API와 오용된 View API를 조정하여 앱 경계를 반환합니다. Display API의 경우 ALWAYS_SANDBOX_DISPLAY_APIS, View API의 경우 OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS입니다. ALWAYS_SANDBOX_DISPLAY_APIS는 크기 호환성 모드를 사용할 수 있는 앱에도 기본적으로 적용됩니다.

투명한 활동

투명한 활동은 다음과 같은 투명한 배경 스타일의 결과입니다.

<style name="Transparent" parent="AppTheme">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
</style>

대화상자와 관련된 테마(예: Theme.Material.Dialog)에는 활동을 투명하게 만드는 스타일이 포함될 수 있습니다.

투명한 활동은 사용 가능한 디스플레이 공간을 모두 차지하지는 않습니다. 따라서 대형 화면에서는 처리하기가 쉽지 않습니다. 사용 가능한 디스플레이 영역이 기기 회전, 기기 접기 및 펼치기, 멀티 윈도우 모드와 같은 구성 변경에 따라 변경될 수 있기 때문입니다.

문제

대형 화면에서 투명한 활동은 작업 활동 스택의 투명한 활동 아래에 있는 첫 번째 불투명 활동의 경계를 준수해야 합니다. 그러나 권한 대화상자를 실행하는 불투명 활동은 대화상자를 실행한 후 사라지는 트램펄린(다른 활동을 실행하는 활동)일 수 있습니다. 따라서 시스템은 투명한 활동 아래에 있는 불투명 활동의 경계를 결정할 수 없습니다.

최적화

반투명 활동은 작업의 활동 스택에서 그 아래에 있는 최상위 불투명 활동에서 제약 조건을 상속받습니다. 불투명 활동은 활동 생성부터 소멸까지 반투명 활동의 전체 수명 주기에서 사용할 수 있어야 합니다. 따라서 트램펄린 활동에서 권한 요청을 실행하면 안 됩니다.

트램펄린 활동이 권한 요청을 실행하면 사용자에게 권한 대화상자가 표시되지 않을 수 있습니다. 트램펄린 활동이 사용자가 대화상자에 응답하기 전에 소멸되기 때문입니다.

앱은 사용자가 권한을 결정할 때까지 계속 표시되는 활동에서 항상 권한 요청을 실행해야 합니다.

둥근 모서리

활동은 반투명 테마를 사용하거나 사용할 수 있는 디스플레이 공간을 채우지 않음으로써 반투명해질 수 있습니다. 반투명 활동이 사용 가능한 디스플레이 공간을 채우면 시스템은 기기 제조업체에서 구성한 경우 활동에 둥근 모서리를 자동으로 적용합니다. 하지만 반투명 활동이 사용할 수 있는 공간을 채우지 않으면(예: 권한 대화상자) 둥근 모서리를 적용할지 여부는 개발자가 결정합니다.

권한 대화상자는 사용 가능한 디스플레이 공간을 채우지 않습니다. 일반적으로 대화상자 레이아웃이 LayoutParams.MATCH_PARENT가 아닌 LayoutParams.WRAP_CONTENT를 사용하기 때문입니다.

호환성 해결 방법

대화상자 활동을 실행하는 활동은 사용자가 대화상자에 응답할 때까지 계속 표시되도록 합니다.

시스템은 투명한 활동이 활동 스택의 투명한 활동 아래에 있는 첫 번째 불투명 활동에서 모든 제약 조건을 상속받도록 합니다. 여기에는 다음과 관련된 제약 조건이 포함됩니다.

  • 크기 호환성 모드
  • 방향
  • 가로세로 비율

Unity 게임

Unity 게임은 Android 전체 화면 또는 멀티 윈도우 모드에서 실행됩니다. 그러나 대부분의 Unity 게임은 앱이 멀티 윈도우 모드에 있을 때 포커스를 잃고 콘텐츠 그리기를 중지합니다.

문제

Unity에서는 Unity 2019.4 이후 Android의 멀티 윈도우 모드를 지원하는 Resizable Window 옵션을 추가했습니다. 그러나 초기 구현이 멀티 윈도우 모드의 활동 수명 주기에 올바르게 반응하지 않아 앱에 포커스가 없을 때 UnityPlayer에서 재생을 정지했습니다. 플레이어가 게임의 검은색 화면 또는 마지막으로 정지된 프레임을 렌더링했습니다. 게임플레이는 사용자가 화면을 탭할 때만 재개되었습니다. Unity 엔진을 사용하는 많은 앱에서 이 문제가 발생하여 멀티 윈도우 모드에서 검은색 창으로 렌더링됩니다.

최적화

Unity를 2019.4.40 이상으로 업그레이드하고 게임을 다시 내보내세요. Android 플레이어 설정에서 Resizable Window 옵션을 선택된 상태로 유지합니다. 그러지 않으면 게임이 멀티 윈도우 모드에서 완전히 표시되더라도 포커스가 없을 때 일시중지됩니다.

호환성 해결 방법

OEM은 OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS 앱별 재정의를 적용하여 멀티 윈도우 모드에서 앱에 가짜 포커스 이벤트를 제공할 수 있습니다. 재정의를 통해 활동이 콘텐츠를 다시 그릴 수 있고 블랙아웃되지 않습니다.

앱의 호환성 문제 테스트

앱을 테스트하고 다양한 폼 팩터에서 어떻게 동작하는지 이해하려면 다음 리소스를 활용해 보세요.

  • 기기 스트리밍: Google 데이터 센터에서 호스팅되는 프로덕션 기기(Pixel Tablet 및 Pixel Fold 포함)에서 앱을 테스트하려면 Android 스튜디오에서 Android 기기 스트리밍을 참고하세요.
  • Android 스튜디오 Hedgehog의 Pixel Tablet 및 Pixel Fold 에뮬레이터: Pixel Tablet 및 Pixel Fold용 에뮬레이터 만들기에 관한 자세한 내용은 가상 기기 만들기 및 관리를 참고하세요.
  • Android 스튜디오 크기 조절 가능한 에뮬레이터: 가상 기기 액세스에 관한 자세한 내용은 Android Emulator에서 앱 실행을 참고하세요.

레터박스 처리됨

각 활동이 앱에서 사용 가능한 모든 디스플레이 공간을 사용할 수 있는지 확인합니다. 먼저 테스트 폴더에서 다음 코드를 선언합니다.

Kotlin

fun Activity.isLetterboxed() : Boolean {
    if (isInMultiWindowMode) return false

    val wmc = WindowMetricsCalculator.getOrCreate()
    val currentBounds = wmc.computeCurrentWindowMetrics(this).bounds
    val maxBounds = wmc.computeMaximumWindowMetrics(this).bounds

    val isScreenPortrait = maxBounds.height() > maxBounds.width()

    return if (isScreenPortrait) {
        currentBounds.height() < maxBounds.height()
    } else {
        currentBounds.width() < maxBounds.width()
    }
}

Java

public boolean isLetterboxed(Activity activity) {
    if (activity.isInMultiWindowMode()) {
        return false;
    }

    WindowMetricsCalculator wmc = WindowMetricsCalculator.getOrCreate();
    Rect currentBounds = wmc.computeCurrentWindowMetrics(activity).getBounds()      
    Rect maxBounds = wmc.computeMaximumWindowMetrics(activity).getBounds();
      
    boolean isScreenPortrait = maxBounds.height() > maxBounds.width();

    return (isScreenPortrait)
        ? currentBounds.height() < maxBounds.height()
        : currentBounds.width() < maxBounds.width();
}

그런 다음 테스트를 실행하여 이 동작을 어설션하고 타겟 활동이 레터박스 처리되지 않았는지 확인합니다.

Kotlin

@get:Rule
val activityRule = ActivityScenarioRule(MainActivity::class.java)

@Test
fun activity_launched_notLetterBoxed() {
    activityRule.scenario.onActivity {
        assertThat(it.isLetterboxed()).isFalse()
    }
}

Java

@Rule
public ActivityScenarioRule rule = new ActivityScenarioRule<>(MainActivity.class);

public void activity_launched_notLetterBoxed() {
    try (ActivityScenario scenario = ActivityScenario.launch(MainActivity.class)) {
        scenario.onActivity(activity -> {
            assertThat(isLetterboxed(activity)).isFalse();
        });
    }
}

이런 종류의 테스트는 앱의 활동이 테스트를 통과하여 앱에서 사용 가능한 전체 디스플레이 공간을 차지한다고 어설션할 때까지만 실행하는 것이 이상적입니다. 일관된 동작을 보장할 수 있도록 모든 기기 유형에서 앱을 테스트하세요.

앱별 재정의

Android는 앱의 구성된 동작을 변경할 수 있는 재정의를 제공합니다. 예를 들어 FORCE_RESIZE_APP 재정의는 앱 매니페스트에 resizeableActivity="false"가 설정되어 있더라도 시스템에 크기 호환성 모드를 우회하라고 지시합니다.

OEM은 특정 대형 화면 기기에 앱별로 재정의를 적용합니다. Pixel Tablet과 Pixel Fold는 기본적으로 일부 재정의를 다양한 앱에 적용합니다.

호환성 프레임워크를 사용하여 재정의를 사용 설정하거나 사용 중지한 상태로 앱을 테스트할 수 있습니다(호환성 프레임워크 도구 참고). 사용 설정하면 재정의가 전체 앱에 적용됩니다.

또한 Android 디버그 브리지(adb)를 사용하여 재정의를 사용 설정하거나 사용 중지할 수 있고 앱에 적용할 재정의를 결정할 수 있습니다.

다음과 같이 재정의를 사용 설정 또는 중지합니다.

adb shell am compat enable/disable <override name/id> <package>

Pixel Tablet 및 Pixel Fold의 경우 앱에 적용되는 재정의를 확인합니다.

adb shell dumpsys platform_compat | grep <package name>

다음 표에는 사용 가능한 재정의와 앱이 재정의에 의존하지 않아도 되도록 앱을 최적화하는 방법에 관한 안내가 나열되어 있습니다. 속성 플래그를 앱 매니페스트에 추가하여 일부 재정의를 선택 해제할 수 있습니다.

앱별 재정의
유형 이름 ID 설명
크기 조정 가능 여부 FORCE_RESIZE_APP 174042936 구성 변경 시 앱의 크기 호환성 모드를 우회합니다.
FORCE_NON_RESIZE_APP 181136395 구성 변경 시 앱이 크기 호환성 모드로 강제 전환됩니다.
가로세로 비율 OVERRIDE_MIN_ASPECT_RATIO 174042980 다른 가로세로 비율 재정의를 적용하려면 게이트키퍼 재정의를 사용 설정해야 합니다.
OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY 203647190 사용 설정하면(기본값) 재정의 범위가 세로 모드 전용 활동으로 제한됩니다.
OVERRIDE_MIN_ASPECT_RATIO_MEDIUM 180326845 최소 가로세로 비율을 3:2로 변경합니다.
OVERRIDE_MIN_ASPECT_RATIO_LARGE 180326787 최소 가로세로 비율을 16:9로 변경합니다.
OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN 208648326 디스플레이 크기의 50%(또는 화면 분할 가로세로 비율)에 맞게 최소 가로세로 비율을 변경합니다.
OVERRIDE_MIN_ASPECT_RATIO_EXCLUDE_PORTRAIT_FULLSCREEN 218959984 기기가 세로 모드일 때 앱이 전체 화면으로 표시되도록 최소 가로세로 비율 재정의를 사용 중지합니다.
방향 OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT 265452344 활동에 방향이 정의되지 않은 경우 방향이 세로 모드가 되도록 재정의합니다.
OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR 265451093 활동에 방향이 정의되지 않은 경우 방향이 nosensor(기기의 자연스러운 방향 사용)가 되도록 재정의합니다.
OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE 266124927 가로 모드 전용 앱을 180도 회전합니다.
OVERRIDE_ANY_ORIENTATION 265464455 모든 방향 재정의를 사용 설정합니다.
OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA 265456536 방향 재정의 범위를 앱이 카메라에 연결될 때로 제한합니다.
OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION 255940284 작업이 전체 화면일 때(레터박스일 때도 포함) 고정된 가로 모드의 자연스러운 방향으로 디스플레이를 설정합니다.
OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION 254631730 순환 루프를 방지하기 위해 앱의 방향 요청을 무시합니다.
OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED 273509367 활동이 다시 실행되는 동안 반복되는 방향 요청을 무시합니다. Android는 앱이 1초에 새로운 방향을 두 번 이상 요청한다고 감지하면 이를 순환 루프로 간주하고 재정의를 적용합니다.
OVERRIDE_RESPECT_REQUESTED_ORIENTATION 236283604 OEM 방향 요청 무시 설정을 사용 중지하여 레터박스를 방지합니다.
Sandbox API NEVER_SANDBOX_DISPLAY_APIS 184838306 디스플레이 API의 동작을 변경하지 못하게 합니다.
ALWAYS_SANDBOX_DISPLAY_APIS 185004937 앱의 Display API가 앱 경계를 반환하도록 강제합니다. Display API는 디스플레이 영역 경계를 반환하지만 앱에서는 Display API가 앱 경계를 반환한다고 가정하여 UI 문제를 일으키는 경우도 있습니다.
OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS 237531167 앱에서 사용되는 View API가 앱 경계를 반환하도록 강제합니다. View API는 디스플레이 영역 경계를 반환하지만 앱에서는 View API가 앱 경계를 반환한다고 가정하여 UI 문제가 발생하기도 합니다.
카메라 호환성 OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION 263959004 강제 회전을 사용 중지합니다. 기본적으로 모든 고정 방향 카메라 앱은 카메라 미리보기가 열릴 때 강제로 회전됩니다.
OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH 264304459 카메라 미리보기가 강제 회전될 때 적용되는 기본 하드 새로고침을 삭제합니다.
OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE 264301586 카메라 미리보기가 강제로 회전될 때 하드 새로고침을 소프트 새로고침으로 전환합니다. 이렇게 하면 강제로 회전하는 동안 상태가 유지될 수 있습니다. 기본적으로 Android는 카메라 미리보기가 강제로 회전될 때 하드 새로고침을 적용합니다. 하드 새로고침은 특정 앱이 이전 상태를 캐시한 방식에 따라 상태가 손실되거나 블랙아웃되는 문제가 발생할 수 있습니다.
OVERRIDE_CAMERA_LANDSCAPE_TO_PORTRAIT 250678880 내부 전면 카메라의 이미지 버퍼를 자릅니다. 재정의를 사용 중지하면 내부 전면 카메라 자르기가 삭제되고 카메라 미리보기의 시야가 증가합니다. 기본적으로 Pixel Fold에서는 시스템이 내부 전면 카메라를 사용할 때 모든 카메라 앱의 카메라 미리보기를 자릅니다.
기타 OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS 263259275 앱이 화면 분할 모드에서 포커스를 잃을 때 블랙아웃되는 것을 방지합니다. 앱은 앱 콘텐츠를 그리기 전에 포커스를 기다리며 이로 인해 앱이 정지되거나 블랙아웃될 수 있습니다. 재정의를 사용하면 Android에서 앱에 가짜 포커스 이벤트를 전송하고 이는 앱에 콘텐츠 그리기를 다시 시작하도록 알립니다.

FORCE_RESIZE_APP

재정의가 적용되는 패키지의 크기를 조절할 수 있도록 강제합니다. 앱을 멀티 윈도우 모드로 전환할 수 있는지는 변경하지 않지만 화면 크기가 조절될 때 크기 호환성 모드로 전환하지 않고도 앱의 크기를 조절할 수 있습니다.

앱이 재정의와 동일한 결과를 달성하는 방법

앱 매니페스트에서 android:resizeableActivity 속성을 true로 설정하거나 android.supports_size_changes 메타데이터 플래그를 true로 설정합니다(android:resizeableActivity를 false로 설정하여 멀티 윈도우 모드를 사용 중지하는 동안 크기 조절 지원).

앱 최적화 방법

반응형/적응형 레이아웃을 사용하면 앱을 모든 디스플레이 크기 및 가로세로 비율에 맞게 조정할 수 있습니다. 다양한 화면 크기 지원을 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

속성 플래그 PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES를 false로 설정합니다.

재정의를 조정하는 속성 플래그

<property android:name="android.window.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES"
  android:value="true|false"/>

재정의를 테스트하는 adb 명령어

재정의를 적용하고 앱의 크기를 조절할 수 있도록 하려면 다음을 실행합니다.

adb shell am compat enable FORCE_RESIZE_APP <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable FORCE_RESIZE_APP <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

FORCE_NON_RESIZE_APP

재정의가 적용되는 패키지의 크기를 조절할 수 없도록 강제하고 구성 변경 시 크기 호환성 모드로 전환되도록 합니다.

앱이 재정의와 동일한 결과를 달성하는 방법

앱 매니페스트에서 android:resizeableActivity 속성과 android.supports_size_changes 메타데이터 플래그를 모두 false로 설정하고 방향 또는 가로세로 비율 제한을 선언합니다.

앱 최적화 방법

크기를 조절해도 제대로 작동하는 모든 앱은 android:resizeableActivity 또는 android.supports_size_changes가 true로 설정되어 있어야 합니다. 다른 앱은 크기가 조절될 때 잘 작동하도록 개선되어야 합니다. android:resizeableActivity를 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

속성 플래그 PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES를 false로 설정합니다.

재정의를 조정하는 속성 플래그

<property android:name="android.window.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES"
  android:value="true|false"/>

재정의를 테스트하는 adb 명령어

재정의를 적용하고 앱의 크기를 조절할 수 없도록 하려면 다음을 실행합니다.

adb shell am compat enable FORCE_NON_RESIZE_APP <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable FORCE_NON_RESIZE_APP <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_MIN_ASPECT_RATIO

지정된 최소 가로세로 비율을 강제하는 모든 처리의 게이트키퍼입니다.

앱이 재정의와 동일한 결과를 달성하는 방법

활동 또는 앱 수준에서 android:minAspectRatio를 설정합니다.

앱 최적화 방법

앱에서 가로세로 비율 제한을 설정하면 안 됩니다. 앱이 다양한 화면 크기를 지원하는지 확인하세요. 창 크기 클래스를 사용하여 화면에서 앱이 차지하는 공간의 크기에 따라 다양한 레이아웃을 지원합니다. Compose WindowSizeClass APIView WindowSizeClass API를 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

가로세로 비율 제한을 지정하거나 속성 플래그 PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE를 false로 설정하세요.

재정의를 조정하는 속성 플래그

<property android:name="android.window.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE"
  android:value="false"/>

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_MIN_ASPECT_RATIO <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_MIN_ASPECT_RATIO <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY

세로 모드 전용 방향인 활동에 지정된 최소 가로세로 비율을 강제하는 처리를 제한합니다. 기본적으로 사용 설정되며 OVERRIDE_MIN_ASPECT_RATIO도 사용 설정된 경우에만 적용됩니다.

앱이 재정의와 동일한 결과를 달성하는 방법

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

앱 최적화 방법

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

재정의를 조정하는 속성 플래그

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_MIN_ASPECT_RATIO_MEDIUM

활동의 최소 가로세로 비율을 중간 값(3:2)으로 설정합니다.

앱이 재정의와 동일한 결과를 달성하는 방법

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

앱 최적화 방법

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

재정의를 조정하는 속성 플래그

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_MIN_ASPECT_RATIO_MEDIUM <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_MIN_ASPECT_RATIO_MEDIUM <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_MIN_ASPECT_RATIO_LARGE

활동의 최소 가로세로 비율을 큰 값(16:9)으로 설정합니다.

앱이 재정의와 동일한 결과를 달성하는 방법

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

앱 최적화 방법

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

재정의를 조정하는 속성 플래그

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_MIN_ASPECT_RATIO_LARGE <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_MIN_ASPECT_RATIO_LARGE <package>`

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN

화면 분할 가로세로 비율을 사용 설정합니다. 앱이 화면 분할 모드에서 사용 가능한 모든 공간을 사용하도록 허용하여 레터박스를 방지합니다.

앱이 재정의와 동일한 결과를 달성하는 방법

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

앱 최적화 방법

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

재정의를 조정하는 속성 플래그

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_MIN_ASPECT_RATIO_EXCLUDE_PORTRAIT_FULLSCREEN

세로 모드 전체 화면에서 최소 가로세로 비율 재정의를 사용 중지하여 사용할 수 있는 모든 화면 공간을 사용합니다.

앱이 재정의와 동일한 결과를 달성하는 방법

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

앱 최적화 방법

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

재정의를 조정하는 속성 플래그

OVERRIDE_MIN_ASPECT_RATIO를 참고하세요.

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_MIN_ASPECT_RATIO_EXCLUDE_PORTRAIT_FULLSCREEN <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_MIN_ASPECT_RATIO_EXCLUDE_PORTRAIT_FULLSCREEN <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT

패키지의 모든 활동에 세로 모드 방향을 사용 설정합니다. OVERRIDE_ANY_ORIENTATION이 사용 설정되지 않으면 재정의는 활동에서 다른 고정 방향을 지정하지 않은 경우에만 사용됩니다.

앱이 재정의와 동일한 결과를 달성하는 방법

activity:screenOrientation 매니페스트 속성을 설정하거나 Activity#setRequestedOrientation API를 사용합니다.

앱 최적화 방법

앱은 모든 방향을 지원해야 합니다. 방향 변경은 구성 변경이며 다음 두 가지 방법 중 하나로 처리할 수 있습니다. 시스템에서 앱을 소멸시키고 다시 만들도록 하거나 구성 변경을 직접 관리하는 것입니다. 구성 변경을 직접 관리하는 경우 앱 상태는 ViewModel을 사용하여 유지할 수 있습니다. 매우 제한된 경우에 작은 디스플레이에서만 방향을 잠글 수 있습니다. 이렇게 하더라도 크기가 조정되지 않고 사용자가 필요에 따라 앱을 회전할 수 있습니다. Android 12L 및 이후 버전에서는 기기 구성에 따라 고정 방향이 재정의될 수 있습니다. 구성 변경 처리 및 모든 방향 지원에 관한 자세한 내용은 구성 변경 처리, ViewModel 개요, 휴대전화에서는 앱 방향이 제한되지만 대형 화면 기기에서는 제한되지 않음을 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

속성 플래그 PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE를 false로 설정합니다.

재정의를 조정하는 속성 플래그

<property android:name="android.window.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE"
  android:value="true|false"/>

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR

패키지의 모든 활동에 nosensor 방향을 사용 설정합니다. OVERRIDE_ANY_ORIENTATION이 사용 설정되지 않으면 재정의는 활동에서 다른 고정 방향을 지정하지 않은 경우에만 사용됩니다.

앱이 재정의와 동일한 결과를 달성하는 방법

activity:screenOrientation 매니페스트 속성을 설정하거나 Activity#setRequestedOrientation API를 사용합니다.

앱 최적화 방법

OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT을 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

속성 플래그 PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE를 false로 설정합니다.

재정의를 조정하는 속성 플래그

<property android:name="android.window.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE"
  android:value="true|false"/>

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE

패키지의 모든 활동에 reverseLandscape 방향을 사용 설정합니다. OVERRIDE_ANY_ORIENTATION이 사용 설정되지 않으면 재정의는 활동에서 다른 고정 방향을 지정하지 않은 경우에만 사용됩니다.

앱이 재정의와 동일한 결과를 달성하는 방법

activity:screenOrientation 매니페스트 속성을 설정하거나 Activity#setRequestedOrientation API를 사용합니다.

앱 최적화 방법

OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT을 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

속성 플래그 PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE를 false로 설정합니다.

재정의를 조정하는 속성 플래그

<property android:name="android.window.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE"
  android:value="true|false"/>

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_ANY_ORIENTATION

OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT, OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR, OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE 재정의를 허용하여 모든 방향을 재정의합니다.

앱이 재정의와 동일한 결과를 달성하는 방법

activity:screenOrientation 매니페스트 속성을 설정하거나 Activity#setRequestedOrientation API를 사용합니다.

앱 최적화 방법

OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT을 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

속성 플래그 PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE를 false로 설정합니다.

재정의를 조정하는 속성 플래그

<property android:name="android.window.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE"
  android:value="true|false"/>

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_ANY_ORIENTATION <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_ANY_ORIENTATION <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA

OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT, OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR, OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE 재정의를 카메라 연결이 활성 상태일 때만 적용되도록 제한합니다.

앱이 재정의와 동일한 결과를 달성하는 방법

activity:screenOrientation 매니페스트 속성을 설정하거나 Activity#setRequestedOrientation API를 사용합니다.

앱 최적화 방법

OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT을 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

속성 플래그 PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE를 false로 설정합니다.

재정의를 조정하는 속성 플래그

<property android:name="android.window.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE"
  android:value="true|false"/>

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION

다음 조건이 충족되면 디스플레이 방향을 가로 모드의 자연스러운 방향으로 제한합니다.

  • 활동이 전체 화면으로 표시됨
  • 선택 해제 구성요소 속성 PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE가 사용 설정되지 않음
  • 방향 요청 무시 OEM 설정이 디스플레이에 사용 설정됨
  • 디스플레이의 자연스러운 방향이 가로 모드임

앱이 재정의와 동일한 결과를 달성하는 방법

적용할 수 없습니다. 이 문제는 애플리케이션 로직에서 해결해야 합니다.

앱 최적화 방법

OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT을 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

속성 플래그 PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE를 false로 설정합니다.

재정의를 조정하는 속성 플래그

<property android:name="android.window.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE"
  android:value="true|false"/>

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION

앱이 다시 실행 중이거나 앱에 활성 카메라 호환성 처리가 있을 때 Activity#setRequestedOrientation()을 호출하는 앱에 대한 응답으로 앱 방향 업데이트를 건너뛰는 호환성 정책을 사용 설정합니다.

앱이 재정의와 동일한 결과를 달성하는 방법

속성 플래그 PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION를 true로 설정합니다.

앱 최적화 방법

OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT을 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

속성 플래그 PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION를 false로 설정합니다.

재정의를 조정하는 속성 플래그

<property android:name="android.window.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION"
  android:value="true|false"/>

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED

활동이 고정된 방향으로 레터박스 처리되지 않은 경우 Activity#setRequestedOrientation()을 1초에 2회 넘게 호출하는 앱에 대한 응답으로 앱의 요청된 방향을 무시하는 호환성 정책이 사용 설정됩니다.

앱이 재정의와 동일한 결과를 달성하는 방법

적용할 수 없습니다. 이 문제는 애플리케이션 로직에서 해결해야 합니다.

앱 최적화 방법

OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT을 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

속성 플래그 PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED를 false로 설정합니다.

재정의를 조정하는 속성 플래그

<property android:name="android.window.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED"
  android:value="false"/>

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_RESPECT_REQUESTED_ORIENTATION

기기 제조업체가 디스플레이 영역이나 전체 디스플레이에 사용 설정할 수 있는 방향 요청 무시 동작에서 패키지를 제외합니다.

앱이 재정의와 동일한 결과를 달성하는 방법

적용할 수 없습니다. 이 문제는 애플리케이션 로직에서 해결해야 합니다.

앱 최적화 방법

OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT을 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

선택 해제할 수 없습니다. 앱이 OEM 방향 요청 무시 설정이 사용 설정된 기기와 호환되지 않는 경우 재정의를 사용 중지하면 위험할 수 있습니다. 재정의를 사용 중지하려면 Android 개발자 관계팀에 문의하세요.

재정의를 조정하는 속성 플래그

이 재정의의 속성 플래그가 없습니다.

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_RESPECT_REQUESTED_ORIENTATION <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_RESPECT_REQUESTED_ORIENTATION <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

NEVER_SANDBOX_DISPLAY_APIS

패키지가 레터박스 또는 크기 호환성 모드 활동에 Display API 샌드박스를 적용하지 않도록 합니다. Display API는 계속해서 디스플레이 영역 경계를 제공합니다.

앱이 재정의와 동일한 결과를 달성하는 방법

android:resizeableActivity 매니페스트 속성을 true로 설정하거나 android.supports_size_changes 메타데이터 플래그를 true로 설정하여 크기 조절이 가능한 활동을 선언합니다.

앱 최적화 방법

완전히 크기 조절이 가능하다고 선언하는 앱은 디스플레이 크기에 의존하여 UI 요소를 배치해서는 안 됩니다. WindowMetrics를 제공하는 최신 API로 앱을 이전하세요. Jetpack Compose를 사용하는 경우 WindowSizeClass API를 활용하여 앱이 현재 디스플레이에서 화면 영역을 얼마나 차지하는지에 따라 UI를 그립니다. 다양한 화면 크기 지원을 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

선택 해제할 수 없습니다. 지원 중단된 API에서 이전합니다.

재정의를 조정하는 속성 플래그

이 재정의의 속성 플래그가 없습니다.

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable NEVER_SANDBOX_DISPLAY_APIS <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable NEVER_SANDBOX_DISPLAY_APIS <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

ALWAYS_SANDBOX_DISPLAY_APIS

윈도잉 모드와 관계없이 패키지에서 항상 Display API 샌드박스를 적용하도록 강제합니다. Display API는 항상 앱 경계를 제공합니다.

앱이 재정의와 동일한 결과를 달성하는 방법

android:resizeableActivity 속성을 false로 설정하거나 android.supports_size_changes 메타데이터 플래그를 false로 설정하여 크기를 조절할 수 없는 활동을 선언합니다.

앱 최적화 방법

완전히 크기 조절이 가능하다고 선언하는 앱은 디스플레이 크기에 의존하여 UI 요소를 배치해서는 안 됩니다. 지원 중단된 API에서 WindowMetrics를 제공하는 최신 API로 앱을 이전하세요. WindowMetricsCalculator를 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

선택 해제할 수 없습니다. 지원 중단된 API에서 이전합니다.

재정의를 조정하는 속성 플래그

이 재정의의 속성 플래그가 없습니다.

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable ALWAYS_SANDBOX_DISPLAY_APIS <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable ALWAYS_SANDBOX_DISPLAY_APIS <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS

패키지에서 다음 View API를 활동 경계에 샌드박스 처리하도록 강제합니다.

앱이 재정의와 동일한 결과를 달성하는 방법

기기 디스플레이의 경계와 기기 디스플레이 관련 오프셋이 아니라 앱 창의 경계와 앱 창 관련 오프셋을 제공하는 API를 사용하여 애플리케이션 코드에서 문제를 해결합니다.

앱 최적화 방법

앱에서는 레터박스와 멀티 윈도우 모드가 앱에 적용될 가능성을 고려하여 View API를 사용해야 합니다. WindowMetricsCalculator를 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

속성 플래그 PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS를 false로 설정합니다.

재정의를 조정하는 속성 플래그

<property android:name="android.window.PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS"
  android:value="false"/>

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION

강제 회전을 사용 중지합니다. 일부 앱에서 사용자 환경을 개선합니다.

앱이 재정의와 동일한 결과를 달성하는 방법

속성 플래그 PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION를 false로 설정합니다.

앱 최적화 방법

캐시된 카메라 센서 방향이나 기기 정보를 사용하지 않습니다. 카메라 호환성 안내는 카메라 뷰파인더 소개카메라 앱에서 크기 조절 가능한 노출 영역 지원을 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

속성 플래그 PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION를 true로 설정합니다.

재정의를 조정하는 속성 플래그

<property android:name="android.window.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION"
  android:value="true|false"/>

재정의를 테스트하는 adb 명령어

강제 회전을 삭제하는 재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION <package>

강제 회전이 발생할 수 있는 재정의를 삭제하려면 다음을 실행하세요.

adb shell am compat disable OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH

강제 회전 후 활동 새로고침을 사용 중지합니다. 새로고침으로 인해 상태 손실이 발생하는 경우 앱의 사용자 환경을 개선합니다.

앱이 재정의와 동일한 결과를 달성하는 방법

속성 플래그 PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH를 false로 설정합니다.

앱 최적화 방법

캐시된 카메라 센서 방향이나 기기 정보를 사용하지 않습니다. 카메라 호환성 안내는 카메라 뷰파인더 소개카메라 앱에서 크기 조절 가능한 노출 영역 지원을 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

속성 플래그 PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH를 true로 설정합니다.

재정의를 조정하는 속성 플래그

<property android:name="android.window.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH"
  android:value="true|false"/>

재정의를 테스트하는 adb 명령어

활동 새로고침을 삭제하는 재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH <package>

활동 새로고침을 허용하는 재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE

카메라 호환성 강제 회전 후 onResume()onStop()onResume() 대신 onResume()onPause()onResume() 주기를 사용하여 활동 새로고침을 실행하도록 적용된 패키지를 만듭니다.

앱이 재정의와 동일한 결과를 달성하는 방법

속성 플래그 PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE를 true로 설정합니다.

앱 최적화 방법

캐시된 카메라 센서 방향이나 기기 정보를 사용하지 않습니다. 카메라 호환성 안내는 카메라 뷰파인더 소개카메라 앱에서 크기 조절 가능한 노출 영역 지원을 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

속성 플래그 PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE를 false로 설정합니다.

재정의를 조정하는 속성 플래그

<property android:name="android.window.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE"
  android:value="true|false"/>

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_CAMERA_LANDSCAPE_TO_PORTRAIT

세로 모드 카메라 방향이 자연스러운 기기 방향과 일치하지 않을 때 카메라 출력이 반대 방향으로 잘리도록 강제합니다. 많은 앱이 이 상황을 처리하지 않으며 늘어난 이미지를 표시합니다.

앱이 재정의와 동일한 결과를 달성하는 방법

속성 플래그 PROPERTY_COMPAT_OVERRIDE_LANDSCAPE_TO_PORTRAIT를 true로 설정합니다.

앱 최적화 방법

캐시된 카메라 센서 방향이나 기기 정보를 사용하지 않습니다. 카메라 호환성 안내는 카메라 뷰파인더 소개카메라 앱에서 크기 조절 가능한 노출 영역 지원을 참고하세요.

재정의 사용 중지 또는 선택 해제 방법

속성 플래그 PROPERTY_COMPAT_OVERRIDE_LANDSCAPE_TO_PORTRAIT를 false로 설정합니다.

재정의를 조정하는 속성 플래그

<property android:name="android.camera.PROPERTY_COMPAT_OVERRIDE_LANDSCAPE_TO_PORTRAIT"
  android:value="true|false"/>

재정의를 테스트하는 adb 명령어

내부 전면 카메라 자르기를 적용하는 재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_CAMERA_LANDSCAPE_TO_PORTRAIT <package>

내부 전면 카메라 자르기를 삭제하는 재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_CAMERA_LANDSCAPE_TO_PORTRAIT <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS

화면 분할 모드에서 포커스가 없는 앱의 가짜 포커스를 보낼 수 있습니다. 일부 게임 엔진은 앱의 콘텐츠를 그리기 전에 포커스를 받기 위해 대기합니다. 따라서 가짜 포커스는 앱이 재개되고 아직 포커스가 없을 때 블랙아웃 상태로 있는 것을 방지하는 데 도움이 됩니다.

앱이 재정의와 동일한 결과를 달성하는 방법

속성 플래그 PROPERTY_COMPAT_ENABLE_FAKE_FOCUS를 true로 설정합니다.

앱 최적화 방법

앱이 여러 방향과 구성 변경을 잘 처리하는 경우에는 이 문제를 방지할 수 있습니다. 대형 화면 앱 품질 가이드라인을 따라 앱을 대형 화면에서 사용할 수 있도록 준비합니다.

Unity 게임 엔진을 실행하는 경우 버전 2019.4.40 이상으로 업그레이드하고 게임을 다시 내보냅니다. Android 플레이어 설정에서 Resizable Window 옵션을 선택된 상태로 둡니다.

재정의 사용 중지 또는 선택 해제 방법

속성 플래그 PROPERTY_COMPAT_ENABLE_FAKE_FOCUS를 false로 설정합니다.

재정의를 조정하는 속성 플래그

<property android:name="android.window.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS"
  android:value="true|false"/>

재정의를 테스트하는 adb 명령어

재정의를 적용하려면 다음을 실행합니다.

adb shell am compat enable OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS <package>

재정의를 삭제하려면 다음을 실행합니다.

adb shell am compat disable OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS <package>

참고: 명령어는 일시적으로 재정의를 적용하거나 삭제합니다.

추가 리소스