Режим совместимости устройств

Android активирует режим совместимости для приложений, которые заявляют об ограничениях по ориентации или изменению размера. Режим совместимости обеспечивает приемлемое поведение приложений на устройствах с большими экранами, складных телефонах-раскладушках и в настольных средах, но с неоптимальной удобностью использования.

Возможность переопределения параметров для каждого приложения позволяет производителям устройств, владельцам виртуальных устройств¹ и пользователям изменять поведение приложений для улучшения их структуры или предотвращения сбоев в работе приложений на отдельных устройствах.

Android 16

Android 16 (уровень API 36) игнорирует ограничения по ориентации экрана, соотношению сторон и возможности изменения размера приложений, чтобы улучшить компоновку приложений на форм-факторах с минимальной шириной >= 600dp.

Следующие параметры, устанавливаемые для каждого приложения отдельно, не работают для приложений, ориентированных на API уровня 36:

Уклоняться

Ваше приложение может ориентироваться на API уровня 36, но отказаться от поведения Android 16, в этом случае параметр OVERRIDE_ANY_ORIENTATION_TO_USER неприменим.

Объявить явное свойство

如需停用 API 级别 36 行为,请声明 PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY 清单属性。

如需停用特定活动,请在 <activity> 元素中设置相应属性:

<activity ...>
    <property
        android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY"
        android:value="true" />
    ...
</activity>

如需为整个应用停用,请在 <application> 元素中设置该属性:

<application ...>
    <property
        android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY"
        android:value="true" />
    ...
</application>

эталонные устройства

Для следующих устройств может потребоваться внесение изменений в настройки отдельных приложений из-за необычных конфигураций или конфигураций, которые плохо поддерживаются приложениями:

  • Планшеты: Естественная ориентация некоторых планшетов, таких как Pixel Tablet, — альбомная. Устройство находится в своей естественной ориентации, когда Display#getRotation() возвращает Surface.ROTATION_0 . Если приложения предполагают, что ROTATION_0 — это портретная ориентация, макеты приложений и предварительный просмотр камеры могут не соответствовать дисплею устройства.
  • Складные устройства в альбомной ориентации: Некоторые складные устройства, такие как Pixel Fold, в сложенном виде находятся в портретной ориентации, а в разложенном — в альбомной. Если приложения предполагают, что в разложенном виде ориентация портретная, это может привести к мерцанию или проблемам с отображением.
  • Складные телефоны-раскладушки: В разложенном виде телефоны-раскладушки обычно имеют вертикальную ориентацию. Но в сложенном виде телефоны, как правило, имеют небольшой дисплей в горизонтальной ориентации. Приложения должны определять и учитывать различные ориентации дисплеев.
  • Внешние дисплеи: На некоторых устройствах можно запускать оконный режим рабочего стола на внешних подключенных дисплеях. Приложениям необходимо запрашивать у внешних дисплеев информацию, такую ​​как размер и разрешение экрана; в противном случае приложения могут делать неверные предположения о дисплеях, что может привести к некорректной работе приложения.
  • Автомобильные дисплеи: Многие, но не все, автомобильные дисплеи имеют горизонтальную ориентацию. Разработка приложений для отображения информации о парковке на автомобильных дисплеях аналогична разработке приложений для планшетов.

Распространенные проблемы совместимости

Приложения чаще всего сталкиваются с проблемами совместимости из-за ограничений по ориентации экрана, ограничений по изменению размера и соотношению сторон, некорректной обработки ориентации предварительного просмотра камеры и неправильного использования API.

Леттербоксинг

Функция Letterboxing размещает приложение в центре экрана или, на больших экранах, сбоку для удобного доступа. Функция Mattes (однотонные полосы или размытые обои) заполняет неиспользуемую область экрана по бокам, сверху и снизу приложения.

Эффект "черных полос" часто встречается на устройствах с большими экранами, поскольку размеры и соотношение сторон дисплея устройства обычно отличаются от размеров и соотношения сторон стандартных телефонов, для которых разработано большинство приложений.

Рисунок 1. Приложение, ограниченное портретной ориентацией, отображается с черными полосами сверху и снизу на планшете с горизонтальной ориентацией и складном планшете.

Проблема

Приложение не поддерживает все конфигурации отображения, поскольку имеет фиксированную ориентацию, фиксированное соотношение сторон или не поддерживает изменение размера.

К параметрам конфигурации, управляющим ориентацией и изменением размера приложения, относятся следующие:

  • screenOrientation : Задает фиксированную ориентацию для приложения. Приложения также могут устанавливать ориентацию во время выполнения, используя Activity#setRequestedOrientation() .

  • resizeableActivity : Указывает, может ли система изменять размер приложений, чтобы они соответствовали окнам разных размеров. В Android 11 (уровень API 30) и ниже указывает, поддерживают ли приложения многооконный режим. В Android 12 (уровень API 31) и выше указывает, поддерживают ли приложения многооконный режим на маленьких экранах ( класс компактного размера окна ). В Android 12 и выше приложения поддерживают многооконный режим на больших экранах (класс среднего или расширенного размера окна) независимо от этой настройки.

  • maxAspectRatio : Задает максимальное соотношение сторон, поддерживаемое приложением. Только приложения с resizeableActivity , установленным в значение false могут устанавливать maxAspectRatio .

  • minAspectRatio : Задает минимальное соотношение сторон, поддерживаемое приложением. Только приложения с resizeableActivity , установленным в значение false могут устанавливать minAspectRatio .

Оптимизация

Приложение должно поддерживать все ориентации и размеры экрана устройств и многооконного режима . Удалите все ограничения по ориентации и фиксированному соотношению сторон из макетов приложения и файла манифеста приложения.

Обходной путь для обеспечения совместимости

Если приложение с фиксированной ориентацией или фиксированным соотношением сторон запускается в окне, размер или ориентация которого напрямую не поддерживаются, Android отображает его с черными полосами сверху и снизу для сохранения непрерывности отображения.

Начиная с Android 12 (уровень API 31) и продолжая с 12L (уровень API 32), платформа применяет множество улучшений к приложениям с черными полосами по бокам. Производители устройств внедряют эти улучшения пользовательского интерфейса. Для того чтобы ваше приложение могло воспользоваться этими улучшениями, вам не потребуется дополнительная разработка.

В Android 12 (уровень API 31) представлены следующие эстетические улучшения, которые могут быть настроены производителями устройств:

  • Закругленные углы: углы окна приложения выглядят более изящно.
  • Прозрачность системной панели: Панели состояния и навигации, которые накладываются поверх приложения, являются полупрозрачными, благодаря чему значки на панелях всегда видны поверх черного фона.
  • Настраиваемое соотношение сторон: соотношение сторон приложения можно настроить для улучшения его внешнего вида.

Рисунок 2. Приложение с черными полосами по бокам и улучшенным пользовательским интерфейсом.

В версию 12L (уровень API 32) добавлены следующие функциональные улучшения:

  • Настраиваемое расположение: на больших экранах производители устройств могут размещать приложение слева или справа от дисплея, что упрощает взаимодействие.

  • Обновленный дизайн кнопки перезагрузки: производители устройств могут изменить внешний вид кнопки перезагрузки в режиме совместимости размеров для лучшего распознавания пользователями.

В Android 13 (уровень API 33) добавлено диалоговое окно с инструкциями для пользователей о размещении приложения с черными полосами на экране или включении черных полос в режиме разделенного экрана:

Рисунок 3. Приложение с черными полосами по бокам и диалогом для обучения пользователя.

режим совместимости размеров

Режим совместимости по размеру — это режим с черными полосами сверху и снизу, который сохраняет соотношение сторон приложения и включает в себя элемент управления перезапуском. Этот элемент управления позволяет пользователям перезапустить приложение и перерисовать экран. Android активирует режим совместимости по размеру для приложений, которые не изменяют свой размер. Когда активность перемещается в контейнер отображения, несовместимый с размерами активности, система может масштабировать приложение, чтобы заполнить экран устройства хотя бы в одном измерении.

К изменениям конфигурации устройства, которые могут активировать режим совместимости размеров, относятся следующие:

  • Вращение устройства
  • Складное устройство: складывание или раскладывание
  • Переключение между полноэкранным режимом и режимом разделенного экрана.

Проблема

Режим совместимости по размеру обычно применяется к действиям, которые имеют ограничения по ориентации или соотношению сторон и настроены (или определены системой) как не подлежащие изменению размера.

Ваше приложение считается изменяемым по размеру — и не будет переведено в режим совместимости по размеру — если оно соответствует любому из следующих критериев:

Если ваше приложение не соответствует ни одному из условий, оно считается не масштабируемым и может быть переведено в режим совместимости размеров.

Оптимизация

Приложение должно поддерживать все размеры экрана. Чтобы сделать ваше приложение изменяемым по размеру, установите атрибут android:resizeableActivity элемента <activity> или <application> в true в манифесте приложения. Разрабатывайте адаптивные макеты для вашего приложения. Для получения дополнительной информации см. разделы «Поддержка различных размеров экрана» и «Поддержка многооконного режима» .

Обходной путь для обеспечения совместимости

Android переводит приложение в режим совместимости размеров, когда система определяет, что отображение приложения с черными полосами сверху и снизу можно улучшить, изменив масштаб приложения так, чтобы оно заполняло окно хотя бы по одному измерению. Система отображает элемент управления перезапуском, который пересоздает процесс приложения, пересоздает активность и перерисовывает экран. См. также Обзор процессов и потоков .

Режим совместимости дисплея

Режим совместимости с дисплеями предотвращает перезапуск приложения при переключении между различными дисплеями, что может привести к изменению конфигурации, например, цветового режима , доступности сенсорного экрана или плотности экрана .

Режим совместимости с дисплеем включен по умолчанию для игр (на основе флага android:appCategory ) для повышения стабильности и непрерывности работы. В отличие от режима совместимости по размеру, режим совместимости с дисплеем не замораживает конфигурацию приложения. Приложение по-прежнему может получать все обновления конфигурации через API, такие как обратный вызов onConfigurationChanged() , но при этом не подвергается прерыванию работы из-за необходимости перезапуска. Это означает, что игры, которые корректно поддерживают такие API, как onConfigurationChanged(), могут по-прежнему быстро обновлять свой пользовательский интерфейс, даже если они находятся в режиме совместимости с дисплеем.

Чтобы отключить режим совместимости с дисплеем и обрабатывать изменения конфигурации в вашем приложении, объявите о поддержке изменений конфигурации в файле AndroidManifest.xml приложения и обрабатывайте изменения конфигурации в функции обратного вызова onConfigurationChanged().

<activity
    android:name=".MyGameActivity"
    android:configChanges="colorMode|touchscreen|density|...">
    ...
</activity>

Мерцающие петли

Если приложение не поддерживает все ориентации экрана, оно может многократно запрашивать новые ориентации при изменении конфигурации, создавая бесконечный цикл, который приводит к мерцанию экрана или бесконечному вращению приложения.

Проблема

В Android 12 (уровень API 31) и выше производители устройств могут настраивать свои устройства таким образом, чтобы они игнорировали ограничения по ориентации экрана, заданные приложениями, и вместо этого применяли режимы совместимости. Например, складное устройство может игнорировать параметр android:screenOrientation="portrait" для активности, когда активность отображается на внутреннем экране устройства, предназначенном для планшетов в альбомной ориентации.

Если ограничения по ориентации экрана игнорируются, приложение может программно установить свою ориентацию, вызвав метод Activity#setRequestedOrientation() . Этот вызов запускает перезапуск приложения, если приложение не обрабатывает изменения конфигурации (см. раздел «Обработка изменений конфигурации »). После перезапуска ограничения по ориентации экрана снова игнорируются, приложение повторяет вызов setRequestedOrientation() , вызов запускает перезапуск приложения и так далее в самоподдерживающемся цикле.

Ещё один способ столкнуться с этим — когда естественная ориентация экрана устройства ( обычная ориентация, определяемая Android) — альбомная (то есть, вызов Display#getRotation() возвращает Surface.ROTATION_0 , в то время как устройство имеет альбомное соотношение сторон). Исторически приложения предполагали, что Display.getRotation() = Surface.ROTATION_0 означает, что устройство находится в портретной ориентации, но это не всегда так, например, на внутреннем экране некоторых складных устройств и некоторых планшетов.

Приложение, работающее в альбомной ориентации на складном внутреннем дисплее, может проверить поворот экрана, получить значение ROTATION_0 , предположить, что естественная ориентация устройства — портретная, и вызвать setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ) для перенастройки макета приложения. После перезапуска приложения (в альбомной ориентации) оно может снова проверить поворот экрана, получить значение ROTATION_0 , вызвать setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) и продолжить бесконечный цикл.

Оптимизация

Приложениям не следует делать следующее:

  • Установите ориентацию по умолчанию с помощью метода Activity#setRequestedOrientation() в методе onCreate() активности, поскольку запрос на изменение ориентации может быть инициирован неожиданно из-за необработанных изменений конфигурации.
  • Предположим, что естественная ориентация устройства ( ROTATION_0 ) — портретная.
  • Задайте ориентацию на основе сигналов, не связанных с текущим размером окна, таких как Display#getRotation() , наличие FoldingFeature или устаревшие API .

Обходной путь для обеспечения совместимости

Android игнорирует вызовы метода Activity#setRequestedOrientation() в следующих ситуациях:

  • Действие уже было перезапущено после предыдущего вызова метода, или же была включена обработка принудительного вращения в соответствии с совместимостью с камерой (см. предварительный просмотр камеры ниже).

    Производители устройств могут применить это поведение к приложению с помощью параметра OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION .

  • В результате выполнения запроса на изменение ориентации экрана за одну секунду было отправлено более двух запросов, что указывает на возникновение зацикливания. Из двух запросов в цикле Android использует тот, который обеспечивает максимальное отображение области приложения.

    Производители устройств могут применить это поведение к приложению с помощью OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED .

  • Владельцы виртуальных устройств переопределили вызов метода на некоторых устройствах.

Предварительный просмотр камеры

Предварительный просмотр изображения (или видоискатель) в приложениях для камер может быть смещен или искажен на планшетах, ноутбуках и складных дисплеях.

См. также предварительный просмотр камеры в оконном режиме рабочего стола .

Проблема

В документе, определяющем совместимость с Android, указано, что датчик изображения камеры «ДОЛЖЕН быть ориентирован таким образом, чтобы длинная сторона камеры совпадала с длинной стороной экрана».

Приложения часто исходят из предположения, что ориентация устройства и сенсора камеры — портретная, что вполне разумно для стандартных мобильных телефонов. Однако естественная ориентация планшетов и ноутбуков, а также их сенсоров камер может быть альбомной. Кроме того, новые форм-факторы, такие как складные устройства, могут иметь несколько естественных ориентаций и несколько сенсоров камер в разных положениях.

Запуск приложения с ориентацией камеры, не ожидаемой приложением, или переключение между разными камерами или экранами устройств (например, складных) может привести к смещению или искажению предварительного просмотра изображения с камеры.

Оптимизация

Приложения камеры должны корректно определять и управлять ориентацией устройства и ориентацией датчика камеры, чтобы отображать правильно выровненное и масштабированное предварительное изображение камеры. Приложения должны рассчитывать поворот устройства, поворот датчика и соотношение сторон экрана или окна, а затем применять результаты к предварительному просмотру камеры. Подробные инструкции см. в разделах « Предварительный просмотр камеры» и «Введение в видоискатель камеры» .

Обходной путь для обеспечения совместимости

Устройство находится в естественной ориентации, когда Display#getRotation() возвращает Surface.ROTATION_0 . Система вычисляет CameraCharacteristics.SENSOR_ORIENTATION , исходя из естественной ориентации устройства. Android выравнивает окно в портретном режиме приложений, ограниченных портретной ориентацией, с естественной ориентацией устройства, чего ожидает большинство приложений. Android также обрезает изображение с датчика камеры, когда ориентация датчика — альбомная, а предварительный просмотр камеры — портретная. Конкретные обходные пути включают следующее:

  • Принудительное вращение предварительного просмотра камеры для приложений, ограниченных портретной ориентацией: приложения, ограниченные портретной ориентацией, ожидают, что естественная ориентация устройства и ориентация датчика камеры будут портретными. Однако в Android 12 (уровень API 31) и выше приложения могут работать в нескольких ориентациях устройства, если производители устройств игнорируют спецификацию ориентации.

    Когда к камере подключается приложение, предназначенное для портретной съемки, Android принудительно поворачивает приложение, чтобы выровнять окно приложения в портретном режиме с естественной ориентацией устройства.

    На некоторых планшетах (см. справочные устройства ) окно приложения в портретном режиме поворачивается в полноэкранный портретный режим, чтобы соответствовать естественной ориентации устройства. После принудительного поворота приложение занимает весь экран.

    На внутреннем экране складных устройств в альбомной ориентации (см. справочные устройства ) действия, доступные только в портретной ориентации, поворачиваются в альбомную ориентацию, чтобы соответствовать естественной ориентации в развернутом состоянии. После принудительного поворота приложение отображается с черными полосами сверху и снизу.

  • Обрезка изображения с внутренней фронтальной камеры: датчик внутренней фронтальной камеры на некоторых складных устройствах имеет альбомную ориентацию. Помимо принудительного поворота предварительного просмотра изображения на внутреннем дисплее складного устройства, Android обрезает поле зрения внутренней фронтальной (альбомной) камеры, чтобы датчик захватывал изображение, противоположное ориентации устройства.

  • Принудительное обновление предварительного просмотра камеры: после принудительного поворота система циклически использует методы активности onStop() и onStart() (по умолчанию) или onPause() и onResume() (применяются с помощью переопределения OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE для каждого приложения), чтобы убедиться в корректном отображении предварительного просмотра камеры.

  • Масштабирование соотношения сторон: система динамически изменяет соотношение сторон предварительного просмотра с камеры, повернутой с усилием, на более высокое минимальное соотношение сторон, что обеспечивает правильное масштабирование предварительного просмотра с камеры.

Разработчики приложений могут обойти эти обходные пути, если приложения корректно обрабатывают предварительный просмотр камеры. См. раздел «Обходные пути для каждого приложения» .

Часто неправильно используемые API

Поскольку Android добавил поддержку таких функций, как многооконный режим, и устройств, таких как складные смартфоны, устаревшие API были признаны устаревшими и заменены современными API, работающими со всеми размерами экранов и форм-факторами устройств. Однако устаревшие API по-прежнему доступны для обеспечения обратной совместимости.

Некоторые API View предназначены для специальных целей, которые не всегда хорошо понимают разработчики.

Проблема

Разработчики продолжают использовать устаревшие API Display и ошибочно предполагают, что эти API возвращают границы приложения, а не границы области отображения устройства. Или же разработчики по ошибке используют специализированные API для представления, чтобы получить общие метрики отображения. В результате возникают ошибки при перемещении элементов пользовательского интерфейса после изменения размера окна приложения, что приводит к проблемам с компоновкой.

Устаревшие и часто неправильно используемые API отображения:

Для получения дополнительной информации см. раздел «Поддержка многооконного режима» .

Неправильное использование API для отображения данных:

Оптимизация

Никогда не полагайтесь на физический размер экрана для позиционирования элементов пользовательского интерфейса. Переведите ваше приложение на API, основанные на WindowMetrics , включая следующие API WindowManager :

Обходной путь для обеспечения совместимости

Два параметра переопределения изменяют устаревшие API Display и неправильно используемые API View , чтобы возвращать границы приложения: ALWAYS_SANDBOX_DISPLAY_APIS для API Display ; OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS для API View . 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.MaterialComponents.Dialog , могут включать стили, которые делают действия прозрачными.

Прозрачные окна не покрывают все доступное пространство экрана, что затрудняет их управление, поскольку доступная область отображения может изменяться в зависимости от изменений конфигурации, таких как поворот устройства, складывание и раскладывание устройства, а также многооконный режим.

Проблема

Прозрачная активность должна соответствовать границам первой непрозрачной активности, расположенной ниже прозрачной активности в стеке задач. Однако непрозрачная активность, запускающая диалоговое окно запроса разрешения, может быть «трамплином» (активностью, которая запускает другую активность, а затем исчезает); поэтому система не может определить границы активности-трамплина, запустившей прозрачное диалоговое окно запроса разрешения.

Оптимизация

Прозрачные действия наследуют свои ограничения от самого верхнего непрозрачного действия, расположенного ниже в стеке действий задачи. Непрозрачное действие должно быть доступно на протяжении всего жизненного цикла прозрачного действия, от создания до уничтожения. По этой причине не следует отправлять запросы на разрешение из действий-трамплинов.

Если активность на батуте запускает запрос на разрешение, пользователь может не увидеть диалоговое окно запроса разрешения, поскольку активность на батуте будет уничтожена до того, как пользователь успеет ответить на него, а размеры и положение активности в диалоговом окне могут быть рассчитаны неправильно.

Приложения всегда должны отправлять запросы на разрешение из действий, которые остаются видимыми до тех пор, пока пользователь не примет решение о предоставлении разрешения.

Закругленные углы

Прозрачность активности может быть обусловлена ​​стилем, задающим прозрачность фона, или тем, что содержимое активности не заполняет доступное пространство экрана. Если прозрачная активность заполняет доступное пространство экрана, система автоматически применяет к ней скругленные углы, если это настроено производителем устройства. Но если прозрачная активность (например, диалоговое окно запроса разрешения) не заполняет доступное пространство, решение о применении скругленных углов остается за вами.

Диалоги разрешений не заполняют доступное пространство экрана, поскольку в макете диалога обычно используется LayoutParams.WRAP_CONTENT , а не LayoutParams.MATCH_PARENT .

Обходной путь для обеспечения совместимости

Действия, запускающие диалоговые окна, должны оставаться видимыми до тех пор, пока пользователь не ответит на диалог.

Система гарантирует, что прозрачное действие наследует все ограничения от первого непрозрачного действия, расположенного под прозрачным действием в стеке действий, включая ограничения, связанные с:

  • режим совместимости размеров
  • Ориентация
  • Соотношение сторон

Игры на юните

Игры на движке Unity запускаются на Android в полноэкранном режиме или в многооконном режиме. Однако многие игры на Unity теряют фокус и перестают отображать контент, когда приложение находится в многооконном режиме.

Проблема

В Unity 2019.4 была добавлена ​​опция Resizable Window для поддержки многооконного режима на Android. Однако первоначальная реализация некорректно реагировала на жизненный цикл активности в многооконном режиме , из-за чего UnityPlayer приостанавливал воспроизведение, когда приложение теряло фокус. Плеер отображал черный экран или последний, застывший кадр игры. Игровой процесс возобновлялся только после касания пользователем экрана. Многие приложения, использующие движок Unity, сталкиваются с этой проблемой и отображаются как черное окно в многооконном режиме.

Оптимизация

Обновите Unity до версии 2019.4.40 или более поздней и повторно экспортируйте игру. Оставьте включенной опцию Resizable Window в настройках Android-плеера , иначе игра будет зависать, когда не находится в фокусе, даже если она полностью видна в многооконном режиме.

Обходной путь для обеспечения совместимости

Производители устройств могут применять параметр OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS для каждого приложения, чтобы обеспечить фиктивное событие фокусировки для приложения в многооконном режиме. Этот параметр позволяет приложению перерисовывать контент, не затемняя его.

Оконный рабочий стол

При работе приложений в оконной среде рабочего стола могут возникать дополнительные режимы совместимости.

Приложения с заблокированной ориентацией экрана можно свободно изменять в размере. Даже если приложение заблокировано в портретной ориентации , пользователи все равно могут изменить его размер на альбомную.

Анимация, демонстрирующая изменение размера приложения для портретной ориентации на альбомную.

Однако, если активность объявлена ​​как неизменяемая по размеру ( resizeableActivity = false ), пользовательский интерфейс активности масштабируется, сохраняя при этом то же соотношение сторон.

Анимация изменения размера приложения. Интерфейс масштабируется, чтобы заполнить окно рабочего стола.

Предварительный просмотр камеры в окне рабочего стола

Когда приложение работает в оконном режиме рабочего стола, поворот экрана и ориентация окон могут отличаться от тех, которые наблюдаются в полноэкранном режиме на стандартных телефонах.

Проблема

Приложения часто предполагают, что ориентация устройства и датчика камеры — портретная, что может привести к смещению или искажению предварительного просмотра изображения с камеры.

Оптимизация

Приложения камеры должны корректно определять и управлять ориентацией устройства и ориентацией датчика камеры, чтобы отображать правильно выровненный и масштабированный предварительный просмотр камеры. Приложения должны вычислять поворот устройства, поворот датчика и соотношение сторон окна, а затем применять результаты к предварительному просмотру камеры, который также должен реагировать на изменения конфигурации окна. Подробные инструкции см. в разделе « Предварительный просмотр камеры» .

Обходной путь для обеспечения совместимости

Когда приложения с фиксированной ориентацией экрана в оконном режиме рабочего стола запускают предварительный просмотр с камеры, система может активировать режим совместимости с камерой, чтобы избежать растянутых и повернутых вбок предварительных просмотров.

В ходе обработки среда изолируется под требуемую ориентацию следующими способами:

  • Затемните окно приложения в нужном ракурсе (например, в формате Letterbox): это позволит избежать проблем с растягиванием из-за некорректного масштабирования.

  • Ограничение поворота экрана: данная процедура имитирует устройство, расположенное в запрошенной ориентации. Поскольку наиболее распространенное неверное предположение для предварительного просмотра камеры заключается в том, что приложение работает на устройстве с портретной ориентацией, поворот экрана ограничивается 0 градусами для приложений, запрашивающих портретную ориентацию, и 90 градусами для устройств, запрашивающих альбомную ориентацию.

  • Кадрирование изображения с камеры: Если изменилось вращение экрана, это отразится на видеопотоке с камеры: если устройство находится в альбомной ориентации, а обработка запускается для приложения, запрашивающего портретную ориентацию, поле зрения камеры обрезается, чтобы оно напоминало поле зрения камеры в портретной ориентации.

  • Поворот и обрезка видеопотока с камеры: после применения обработки система циклически использует методы onStop() и onStart() или onPause() и onResume() (применяемые с помощью переопределения OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE для каждого приложения), чтобы обеспечить корректное отображение предварительного просмотра с камеры.

Разработчики приложений могут обойти эти обходные пути, если приложения корректно обрабатывают предварительный просмотр камеры. См. раздел «Обходные пути для каждого приложения» .

Изменение размера

Когда активна имитация запрошенной ориентации экрана, изменение размера окна масштабирует пользовательский интерфейс видоискателя, сохраняя при этом его соотношение сторон. Остальная часть окна приложения может быть свободно изменена в размере.

Проверьте приложение на наличие проблем совместимости.

Чтобы протестировать ваше приложение и понять, как оно ведет себя на разных форм-факторах, воспользуйтесь следующими ресурсами:

С черными полосами по бокам

Убедитесь, что каждое действие может использовать всё доступное приложению пространство экрана. Сначала объявите следующий код в папке с тестами:

Котлин

fun isLetterboxed(activity: AppCompatActivity): 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(AppCompatActivity 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();
}

Затем проведите тест, чтобы подтвердить правильность поведения и убедиться, что целевое действие не отображается с черными полосами сверху и снизу:

Котлин

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

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

Java

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

@Test
public void activity_launched_notLetterBoxed() {
    try (ActivityScenario<MainActivity> scenario =
        ActivityScenario.launch(MainActivity.class)) {
            scenario.onActivity( activity -> {
                assertFalse(activity.isLetterboxed());
            });
        }
}

В идеале, проводите подобные тесты только до тех пор, пока они не пройдут успешно и не подтвердят, что действия вашего приложения занимают все доступное для него пространство на экране. Протестируйте приложение на всех типах устройств, чтобы обеспечить стабильное поведение.

Переопределения для отдельных приложений

Android предоставляет параметры переопределения, которые изменяют настроенное поведение приложений. Например, параметр FORCE_RESIZE_APP указывает системе игнорировать режим совместимости размеров и изменять размер приложения в соответствии с размерами экрана, даже если в манифесте приложения указано resizeableActivity="false" .

Производители устройств применяют изменения к отдельным приложениям — или ко всем приложениям — на конкретных устройствах. В Android 14 (уровень API 34) и выше пользователи могут применять изменения к приложениям через настройки устройства. В Android 16 (уровень API 36) и выше владельцы виртуальных устройств применяют изменения к отдельным устройствам, которыми они управляют.

Переопределения для каждого приложения пользователем

В Android 14 и выше меню настроек позволяет пользователям изменять соотношение сторон приложений. Это меню реализовано на устройствах с большими экранами, таких как эталонные устройства .

В меню отображается список всех приложений, установленных на устройстве. Пользователи выбирают приложение, а затем устанавливают соотношение сторон приложения на 3:4, 1:1, полноэкранный режим или другое значение, заданное производителем устройства. Пользователи также могут сбросить соотношение сторон до значения по умолчанию, указанного в манифесте приложения.

Приложения могут отказаться от переопределения совместимости, установив следующие теги PackageManager.Property :

  • PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE

    Чтобы отключить учет совместимости с соотношением сторон экрана пользователя, добавьте это свойство в манифест приложения и установите его значение равным false :

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

    Ваше приложение будет исключено из списка приложений в настройках устройства. Пользователи не смогут изменить соотношение сторон приложения.

    Установка свойства в true не даёт никакого эффекта.

  • PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE

    Чтобы отключить полноэкранный режим при настройке совместимости с соотношением сторон экрана, добавьте соответствующее свойство в манифест приложения и установите его значение равным false :

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

    Опция полноэкранного режима удалена из списка параметров соотношения сторон в настройках устройства. Пользователи не смогут применить полноэкранный режим к вашему приложению.

    Установка этого свойства в true не даст никакого эффекта.

Optimize your app for all screens: Don't set aspect ratio restrictions in your app. Use window size classes to support different layouts based on the amount of available display space.

Device per-app overrides

Device manufacturers and virtual device owners (select trusted and privileged apps) apply overrides on a per‑app basis on specific devices, including tablets, foldables, ChromeOS devices, and car displays. The reference devices may apply some of the overrides to a variety of apps by default.

Apps can opt out of most overrides (see the Per-app overrides table below).

You can test your app with overrides enabled or disabled using the compatibility framework (see Compatibility framework tools ). When enabled, overrides apply to the entire app.

You can also use the Android Debug Bridge (adb) to enable or disable overrides and determine which overrides apply to your app.

Enable or disable overrides as follows:

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

For the reference devices , check which overrides apply to your app:

adb shell dumpsys platform_compat | grep <package name>

The following table lists available overrides along with guidance on how to optimize your app so the app does not need to rely on overrides. You can add property flags to your app manifest to opt out of some overrides.

Per-app overrides
Тип Имя ИДЕНТИФИКАТОР Описание
Input Compat OVERRIDE_MOUSE_TO_TOUCH 413207127 Converts MotionEvent instances from a mouse device into touch events by rewriting the MotionEvent source and tool type when they're delivered to the application.
Resizability FORCE_RESIZE_APP 174042936 Bypasses size compatibility mode for app on configuration changes.
FORCE_NON_RESIZE_APP 181136395 Forces app into size compatibility mode on configuration changes.
Соотношение сторон OVERRIDE_MIN_ASPECT_RATIO 174042980 Gatekeeper override that must be enabled to apply any other aspect ratio overrides.
OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY 203647190 If enabled (the default), limits override scope to portrait-only activities.
OVERRIDE_MIN_ASPECT_RATIO_SMALL 349045028 Changes the minimum aspect ratio to 4:3.
OVERRIDE_MIN_ASPECT_RATIO_MEDIUM 180326845 Changes the minimum aspect ratio to 3:2.
OVERRIDE_MIN_ASPECT_RATIO_LARGE 180326787 Changes the minimum aspect ratio to 16:9.
OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN 208648326 Changes the minimum aspect ratio to fit 50% of the display size (or split-screen aspect ratio).
OVERRIDE_MIN_ASPECT_RATIO_EXCLUDE_PORTRAIT_FULLSCREEN 218959984 Disables the minimum aspect ratio override so that apps are full screen when device is portrait.
Ориентация OVERRIDE_ANY_ORIENTATION 265464455 Enables overriding any orientation.
OVERRIDE_ANY_ORIENTATION_TO_USER 310816437 Overrides orientation, resizability, and aspect ratio restrictions.
OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT 265452344 Overrides the orientation to be portrait when an activity has an undefined orientation.
OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR 265451093 Overrides the orientation to be nosensor (use the natural orientation of device) when an activity has an undefined orientation.
OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE 266124927 Rotates landscape-only apps 180 degrees.
OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA 265456536 Limits orientation override scope to when app is connected to the camera.
OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION 255940284 Sets the display to fixed landscape natural orientation when a task is full screen (including when letterboxed).
OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION 254631730 Ignores orientation requests from app to avoid rotation infinite loops.
OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED 273509367 Ignores repeated orientation requests while an activity is relaunching. If Android detects an app is requesting at least two new orientations within one second, the system considers this a rotation infinite loop and applies the override.
OVERRIDE_RESPECT_REQUESTED_ORIENTATION 236283604 Prevents letterboxing by disabling the device manufacturer ignore orientation request setting.
Sandbox APIs NEVER_SANDBOX_DISPLAY_APIS 184838306 Prevents changing the behavior of any display APIs.
ALWAYS_SANDBOX_DISPLAY_APIS 185004937 Forces the Display APIs in the app to return app bounds. Display APIs return logical display area bounds, but sometimes the app assumes Display APIs return app bounds, which leads to UI issues.
OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS 237531167 Forces the View APIs used in the app to return app bounds. View APIs return logical display area bounds, but sometimes the app assumes View APIs return app bounds, which leads to UI issues.
Camera compat OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION 263959004 Turns off force rotation. By default, all fixed-orientation camera apps are force rotated when the camera preview is open.
OVERRIDE_CAMERA_COMPAT_DISABLE_SIMULATE_REQUESTED_ORIENTATION 398195815 Turns off simulating requested orientation treatment for camera compatibility. By default, fixed-orientation camera apps are adjusted based on their requested orientation when the camera preview is open.
OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH 264304459 Removes the default hard refresh applied when a camera preview is force rotated.
OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE 264301586 Switches the hard refresh to a soft refresh when a camera preview is force rotated, which helps preserve state during the force rotation. By default, Android applies a hard refresh when the camera preview is force rotated. The hard refresh can cause issues with apps losing state or blacking out depending on how the apps cached their previous state.
OVERRIDE_CAMERA_LANDSCAPE_TO_PORTRAIT 250678880 Crops the image buffer of the inner front camera. If the override is disabled, the inner front camera cropping is removed and the field of view of the camera preview is increased. By default on some foldables (see reference devices ), the system crops the camera preview of all camera apps when using the inner front camera.
Разнообразный OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS 263259275 Prevents the app from being blacked out when the app loses focus in split-screen mode. App waits for focus before drawing the app content, which can cause the app to freeze or be blacked out. The override enables Android to send a fake focus event to the app, which signals to the app to begin drawing content again.

OVERRIDE_MOUSE_TO_TOUCH

Enables the compatibility treatment that converts MotionEvent instances from a mouse or touchpad to touch events by rewriting the MotionEvent source to SOURCE_TOUCHSCREEN and MotionEvent tool type to TOOL_TYPE_FINGER when the motion events are delivered to the application.

How apps can achieve same result as override

Not applicable. The problem should be solved in the application logic.

How to optimize apps

Your app should handle input events from mouse and touchpad, including touchpad gesture and mouse wheel scrolling. See Keyboard, mouse, and trackpad .

How to disable or opt out of override

Declare FEATURE_PC in a <uses-feature> element in the application's manifest.

<uses-feature android:name="android.hardware.type.pc"
              android:required="false" />

Note: Set android:required="false" so the PC feature is optional and Google Play doesn't exclude the application on non-PC devices.

Property flags to adjust override

Никто.

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_MOUSE_TO_TOUCH <package>

To remove the override:

adb shell am compat disable OVERRIDE_MOUSE_TO_TOUCH <package>

Note: The commands only temporarily apply or remove the override.

FORCE_RESIZE_APP

Forces the packages to which the override is applied to be resizable and able to enter multi‑window mode. Applies to all displays sizes.

How apps can achieve same result as override

In the app manifest, set the android:resizeableActivity attribute to true .

How to optimize apps

Use responsive/adaptive layouts to enable apps to adapt to all display sizes and aspect ratios. See Support different display sizes .

How to disable or opt out of override

Set the property flag PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES to false .

Property flags to adjust override

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

adb commands to test override

To apply the override and make app resizable:

adb shell am compat enable FORCE_RESIZE_APP <package>

To remove the override:

adb shell am compat disable FORCE_RESIZE_APP <package>

Note: The commands only temporarily apply or remove the override.

FORCE_NON_RESIZE_APP

Forces the packages to which the override is applied to be nonresizable and enter size compatibility mode on configuration changes. Applies to all display sizes.

How apps can achieve same result as override

Set both the android:resizeableActivity attribute and android.supports_size_changes metadata flag to false in the app manifest, and declare either an orientation or aspect ratio restriction.

How to optimize apps

All apps that behave well if resized should either have android:resizeableActivity or android.supports_size_changes set to true . Other apps should be improved to behave well when resized. See android:resizeableActivity .

How to disable or opt out of override

Set the property flag PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES to false .

Property flags to adjust override

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

adb commands to test override

To apply the override and make app nonresizable:

adb shell am compat enable FORCE_NON_RESIZE_APP <package>

To remove the override:

adb shell am compat disable FORCE_NON_RESIZE_APP <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_MIN_ASPECT_RATIO

The gatekeeper for all overrides that force a given minimum aspect ratio.

How apps can achieve same result as override

Set android:minAspectRatio at the activity or app level.

How to optimize apps

Don't set aspect ratio restrictions in your app. Make sure your app supports different display sizes . Use window size classes to support different layouts based on the amount of space your app has on the screen. See the Compose WindowSizeClass API and View WindowSizeClass API .

How to disable or opt out of override

Specify an aspect ratio restriction or set the property flag PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE to false .

Property flags to adjust override

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

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_MIN_ASPECT_RATIO <package>

To remove the override:

adb shell am compat disable OVERRIDE_MIN_ASPECT_RATIO <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY

Restricts app settings that force a given minimum aspect ratio for activities with portrait‑only orientation. Enabled by default and only takes effect if OVERRIDE_MIN_ASPECT_RATIO is also enabled.

How apps can achieve same result as override

See OVERRIDE_MIN_ASPECT_RATIO .

How to optimize apps

See OVERRIDE_MIN_ASPECT_RATIO .

How to disable or opt out of override

See OVERRIDE_MIN_ASPECT_RATIO .

Property flags to adjust override

See OVERRIDE_MIN_ASPECT_RATIO .

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY <package>

To remove the override:

adb shell am compat disable OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_MIN_ASPECT_RATIO_SMALL

Sets the activity's minimum aspect ratio to a small value (4:3).

How apps can achieve same result as override

See OVERRIDE_MIN_ASPECT_RATIO .

How to optimize apps

See OVERRIDE_MIN_ASPECT_RATIO .

How to disable or opt out of override

See OVERRIDE_MIN_ASPECT_RATIO .

Property flags to adjust override

See OVERRIDE_MIN_ASPECT_RATIO .

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_MIN_ASPECT_RATIO_SMALL <package>

To remove the override:

adb shell am compat disable OVERRIDE_MIN_ASPECT_RATIO_SMALL <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_MIN_ASPECT_RATIO_MEDIUM

Sets the activity's minimum aspect ratio to a medium value (3:2).

How apps can achieve same result as override

See OVERRIDE_MIN_ASPECT_RATIO .

How to optimize apps

See OVERRIDE_MIN_ASPECT_RATIO .

How to disable or opt out of override

See OVERRIDE_MIN_ASPECT_RATIO .

Property flags to adjust override

See OVERRIDE_MIN_ASPECT_RATIO .

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_MIN_ASPECT_RATIO_MEDIUM <package>

To remove the override:

adb shell am compat disable OVERRIDE_MIN_ASPECT_RATIO_MEDIUM <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_MIN_ASPECT_RATIO_LARGE

Sets the activity's minimum aspect ratio to a large value (16:9).

How apps can achieve same result as override

See OVERRIDE_MIN_ASPECT_RATIO .

How to optimize apps

See OVERRIDE_MIN_ASPECT_RATIO .

How to disable or opt out of override

See OVERRIDE_MIN_ASPECT_RATIO .

Property flags to adjust override

See OVERRIDE_MIN_ASPECT_RATIO .

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_MIN_ASPECT_RATIO_LARGE <package>

To remove the override:

adb shell am compat disable OVERRIDE_MIN_ASPECT_RATIO_LARGE <package>`

Note: The commands only temporarily apply or remove the override.

OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN

Enables the use of split-screen aspect ratio. Allows an app to use all the available space in split-screen mode, avoiding letterboxing.

How apps can achieve same result as override

See OVERRIDE_MIN_ASPECT_RATIO .

How to optimize apps

See OVERRIDE_MIN_ASPECT_RATIO .

How to disable or opt out of override

See OVERRIDE_MIN_ASPECT_RATIO .

Property flags to adjust override

See OVERRIDE_MIN_ASPECT_RATIO .

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN <package>

To remove the override:

adb shell am compat disable OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_MIN_ASPECT_RATIO_EXCLUDE_PORTRAIT_FULLSCREEN

Disables the minimum aspect ratio override in portrait full screen to use all available screen space.

How apps can achieve same result as override

See OVERRIDE_MIN_ASPECT_RATIO .

How to optimize apps

See OVERRIDE_MIN_ASPECT_RATIO .

How to disable or opt out of override

See OVERRIDE_MIN_ASPECT_RATIO .

Property flags to adjust override

See OVERRIDE_MIN_ASPECT_RATIO .

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_MIN_ASPECT_RATIO_EXCLUDE_PORTRAIT_FULLSCREEN <package>

To remove the override:

adb shell am compat disable OVERRIDE_MIN_ASPECT_RATIO_EXCLUDE_PORTRAIT_FULLSCREEN <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_ANY_ORIENTATION

Enables the following overrides to override any orientation:

How apps can achieve same result as override

Set the activity:screenOrientation manifest attribute, or use the Activity#setRequestedOrientation() API.

How to optimize apps

Your app should support all orientations. An orientation change is a configuration change, which can be handled either of two ways: letting the system destroy and recreate the app, or managing the configuration changes yourself. If you manage configuration changes yourself, the app state can be retained by using ViewModel . In very limited cases, you can decide to lock the orientation on small displays only, although doing so might not scale as well as letting the user rotate the app as needed. On Android 12L and higher versions, fixed orientation can be overridden by device configuration. For more information about handling configuration changes and supporting all orientations, see Handle configuration changes , ViewModel overview , and App orientation restricted on phones but not on large screen devices .

How to disable or opt out of override

Set the property flag PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE to false .

Property flags to adjust override

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

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_ANY_ORIENTATION <package>

To remove the override:

adb shell am compat disable OVERRIDE_ANY_ORIENTATION <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_ANY_ORIENTATION_TO_USER

Enables app to fill the available display space. Overrides any orientation, resizability, and aspect ratio restrictions specified in the app manifest. Also ignores any calls to Activity#setRequestedOrientation() or Activity#getRequestedOrientation() .

How apps can achieve same result as override

  • Do not set the android:screenOrientation manifest attribute, or set the attribute to "user" .

  • Set the android:resizeableActivity manifest attribute to true .

  • On small screens, to support app resizing while disabling multi‑window mode with android:resizeableActivity=false , set the android.supports_size_changes metadata flag to true . Do not set minAspectRatio and maxAspectRatio .

How to optimize apps

Enable your app to support all orientations; don't set a screenOrientation specification in your app's manifest. Support app resizability, multi‑window mode, and all display aspect ratios by setting the android:resizeableActivity attribute in your app's manifest to true . See Support different display sizes .

How to disable or opt out of override

See OVERRIDE_ANY_ORIENTATION .

Property flags to adjust override

See OVERRIDE_ANY_ORIENTATION .

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_ANY_ORIENTATION_TO_USER <package>

To remove the override:

adb shell am compat disable OVERRIDE_ANY_ORIENTATION_TO_USER <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT

Enables portrait orientation for all activities in the package. Unless OVERRIDE_ANY_ORIENTATION is enabled, the override is used only when no other fixed orientation has been specified by the activity.

How apps can achieve same result as override

See OVERRIDE_ANY_ORIENTATION .

How to optimize apps

See OVERRIDE_ANY_ORIENTATION .

How to disable or opt out of override

See OVERRIDE_ANY_ORIENTATION .

Property flags to adjust override

See OVERRIDE_ANY_ORIENTATION .

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT <package>

To remove the override:

adb shell am compat disable OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR

Enables nosensor orientation for all activities in the package. Unless OVERRIDE_ANY_ORIENTATION is enabled, the override is used only when no other fixed orientation has been specified by the activity.

How apps can achieve same result as override

See OVERRIDE_ANY_ORIENTATION .

How to optimize apps

See OVERRIDE_ANY_ORIENTATION .

How to disable or opt out of override

See OVERRIDE_ANY_ORIENTATION .

Property flags to adjust override

See OVERRIDE_ANY_ORIENTATION .

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR <package>

To remove the override:

adb shell am compat disable OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE

Enables reverseLandscape orientation for all activities in the package. Unless OVERRIDE_ANY_ORIENTATION is enabled, the override is used only when no other fixed orientation has been specified by the activity.

How apps can achieve same result as override

See OVERRIDE_ANY_ORIENTATION .

How to optimize apps

See OVERRIDE_ANY_ORIENTATION .

How to disable or opt out of override

See OVERRIDE_ANY_ORIENTATION .

Property flags to adjust override

See OVERRIDE_ANY_ORIENTATION .

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE <package>

To remove the override:

adb shell am compat disable OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA

Limits OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT , OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR , and OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE overrides to take effect only when camera connection is active.

How apps can achieve same result as override

See OVERRIDE_ANY_ORIENTATION .

How to optimize apps

See OVERRIDE_ANY_ORIENTATION .

How to disable or opt out of override

See OVERRIDE_ANY_ORIENTATION .

Property flags to adjust override

See OVERRIDE_ANY_ORIENTATION .

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA <package>

To remove the override:

adb shell am compat disable OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION

Restricts display orientation to landscape natural orientation when the following conditions are met:

  • Activity is full screen
  • Opt out component property PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE isn't enabled
  • Device manufacturer ignore orientation request setting is enabled for the display
  • Natural orientation of the display is landscape

How apps can achieve same result as override

Not applicable. The problem should be solved in the application logic.

How to optimize apps

See OVERRIDE_ANY_ORIENTATION .

How to disable or opt out of override

Set the property flag PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE to false .

Property flags to adjust override

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

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION <package>

To remove the override:

adb shell am compat disable OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION

Enables compat policy that skips updating app orientation in response to app calling Activity#setRequestedOrientation() when app is relaunching or has an active camera compat treatment.

How apps can achieve same result as override

Set property flag PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION to true .

How to optimize apps

See OVERRIDE_ANY_ORIENTATION .

How to disable or opt out of override

Set property flag PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION to false .

Property flags to adjust override

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

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION <package>

To remove the override:

adb shell am compat disable OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED

Enables the compatibility policy that ignores an app's requested orientation in response to the app calling Activity#setRequestedOrientation() more than twice in one second if an activity is not letterboxed for fixed orientation.

How apps can achieve same result as override

Not applicable. The problem should be solved in the application logic.

How to optimize apps

See OVERRIDE_ANY_ORIENTATION .

How to disable or opt out of override

Set property flag PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED to false .

Property flags to adjust override

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

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED <package>

To remove the override:

adb shell am compat disable OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_RESPECT_REQUESTED_ORIENTATION

Excludes packages from ignore orientation request behavior that can be enabled by device manufacturers for a display area or the whole display.

How apps can achieve same result as override

Not applicable. The problem should be solved in the application logic.

How to optimize apps

See OVERRIDE_ANY_ORIENTATION .

How to disable or opt out of override

No opt-out. Disabling the override can be dangerous if the app is not compatible with a device that has the device manufacturer ignore orientation request setting enabled. Contact Android Developer Relations to disable the override.

Property flags to adjust override

No property flags for this override.

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_RESPECT_REQUESTED_ORIENTATION <package>

To remove the override:

adb shell am compat disable OVERRIDE_RESPECT_REQUESTED_ORIENTATION <package>

Note: The commands only temporarily apply or remove the override.

NEVER_SANDBOX_DISPLAY_APIS

Forces packages to never have Display API sandboxing applied for a letterboxed or size compatibility mode activity. The Display APIs continue to provide display area bounds.

How apps can achieve same result as override

Declare activities resizable by either setting the android:resizeableActivity manifest attribute to true or the android.supports_size_changes metadata flag to true .

How to optimize apps

Apps that declare they are fully resizable should never rely upon display size to position UI elements. Migrate your app to up‑to‑date APIs that provide WindowMetrics . If you are using Jetpack Compose, take advantage of the WindowSizeClass API to draw the UI based on how much screen area the app has on the current display. See Use window size classes .

How to disable or opt out of override

No opt-out. Migrate from deprecated APIs.

Property flags to adjust override

No property flags for this override.

adb commands to test override

To apply the override:

adb shell am compat enable NEVER_SANDBOX_DISPLAY_APIS <package>

To remove the override:

adb shell am compat disable NEVER_SANDBOX_DISPLAY_APIS <package>

Note: The commands only temporarily apply or remove the override.

ALWAYS_SANDBOX_DISPLAY_APIS

Forces packages to always have Display API sandboxing applied regardless of windowing mode. The Display APIs always provide the app bounds.

How apps can achieve same result as override

Declare activities nonresizable by either setting the android:resizeableActivity attribute to false or the android.supports_size_changes metadata flag to false .

How to optimize apps

Apps that declare they are fully resizable should never rely on display size to position UI elements. Migrate your app from deprecated APIs to up‑to‑date APIs that provide WindowMetrics . See WindowMetricsCalculator .

How to disable or opt out of override

No opt-out. Migrate from deprecated APIs.

Property flags to adjust override

No property flags for this override.

adb commands to test override

To apply the override:

adb shell am compat enable ALWAYS_SANDBOX_DISPLAY_APIS <package>

To remove the override:

adb shell am compat disable ALWAYS_SANDBOX_DISPLAY_APIS <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS

Forces packages to sandbox the following View APIs to activity bounds:

How apps can achieve same result as override

Resolve the issue in application code by using APIs that provide the bounds of the app window and offsets relative to the app window rather than the bounds of the device display and offsets relative to the device display.

How to optimize apps

Apps should use View APIs, taking into account the possibility of letterboxing and multi-window mode being applied to the app. See WindowMetricsCalculator .

How to disable or opt out of override

Set property flag PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS to false .

Property flags to adjust override

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

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS <package>

To remove the override:

adb shell am compat disable OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION

Disables force rotation. Improves the user experience on some apps.

How apps can achieve same result as override

Set property flag PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION to false .

How to optimize apps

Do not rely on cached camera sensor orientation or device information. For camera compatibility guidance, see Introducing Camera Viewfinder and Support resizable surfaces in your camera app .

How to disable or opt out of override

Set property flag PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION to true .

Property flags to adjust override

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

adb commands to test override

To apply the override, which removes force rotation:

adb shell am compat enable OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION <package>

To remove the override, which allows force rotation to happen:

adb shell am compat disable OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_CAMERA_COMPAT_DISABLE_SIMULATE_REQUESTED_ORIENTATION

Disables simulating requested orientation treatment for camera. Improves the user experience on some apps.

How apps can achieve same result as override

Set property flag PROPERTY_CAMERA_COMPAT_ALLOW_SIMULATE_REQUESTED_ORIENTATION to false .

How to optimize apps

Do not rely on cached camera sensor orientation or device information. For camera compatibility guidance, see Introducing Camera Viewfinder and Support resizable surfaces in your camera app .

How to disable or opt out of override

As this property disables the compatibility treatment, you can improve the user experience by taking into account dynamic display rotation changes, sensor orientation of the device, and window and preview size.

Property flags to adjust override

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

adb commands to test override

To apply the override, which removes simulating requested orientation:

adb shell am compat enable OVERRIDE_CAMERA_COMPAT_DISABLE_SIMULATE_REQUESTED_ORIENTATION <package>

To remove the override, which allows simulating requested orientation to happen:

adb shell am compat disable OVERRIDE_CAMERA_COMPAT_DISABLE_SIMULATE_REQUESTED_ORIENTATION <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH

Disables activity refresh after force rotation. Improves the user experience when refresh causes state loss in apps.

How apps can achieve same result as override

Set property flag PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH to false .

How to optimize apps

See OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION .

How to disable or opt out of override

Set property flag PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH to true .

Property flags to adjust override

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

adb commands to test override

To apply the override, which removes activity refresh:

adb shell am compat enable OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH <package>

To remove the override, which allows activity refresh:

adb shell am compat disable OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE

Makes the packages it is applied to do activity refresh using an onResume()onPause()onResume() cycle rather than onResume()onStop()onResume() after camera compatibility force rotation.

How apps can achieve same result as override

Set property flag PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE to true .

How to optimize apps

See OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION .

How to disable or opt out of override

Set property flag PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE to false .

Property flags to adjust override

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

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE <package>

To remove the override:

adb shell am compat disable OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_CAMERA_LANDSCAPE_TO_PORTRAIT

Forces camera output to be cropped to the opposite orientation when portrait camera orientation doesn't align with the natural device orientation. Many apps don't handle this situation and display stretched images otherwise.

How apps can achieve same result as override

Set property flag PROPERTY_COMPAT_OVERRIDE_LANDSCAPE_TO_PORTRAIT to true .

How to optimize apps

See OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION .

How to disable or opt out of override

Set property flag PROPERTY_COMPAT_OVERRIDE_LANDSCAPE_TO_PORTRAIT to false .

Property flags to adjust override

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

adb commands to test override

To apply the override, which applies inner front camera cropping:

adb shell am compat enable OVERRIDE_CAMERA_LANDSCAPE_TO_PORTRAIT <package>

To remove the override, which removes inner front camera cropping:

adb shell am compat disable OVERRIDE_CAMERA_LANDSCAPE_TO_PORTRAIT <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_DISABLE_MEDIA_PROJECTION_SINGLE_APP_OPTION

Prevents apps from opting out of app screen sharing (see Media projection ). Implemented when apps misuse the createConfigForDefaultDisplay() API to force full‑screen capture and jeopardize user privacy by exposing the contents of notifications, which are captured with full‑screen but not app screen sharing, and all apps regardless of windowing mode.

How apps can achieve same result as override

Allow the default media projection behavior (implemented in Android 14, API level 34, with createScreenCaptureIntent() ), which enables users to decide whether to share the full screen or a single app window regardless of windowing mode. Or call createScreenCaptureIntent(MediaProjectionConfig) with a MediaProjectionConfig argument returned from a call to createConfigForUserChoice() .

How to optimize apps

Allow users to select whether to share the entire device display or an app window during media projection, which as of Android 14 is the default behavior.

Make your app resizable ( resizeableActivity="true" ) to support multi‑window mode.

How to disable or opt out of override

Because of the seriousness of user privacy, your app cannot disable or opt out of this override.

Property flags to adjust override

Никто.

adb commands to test override

To apply the override, which cancels the app's opt out of partial screen sharing (that is, enables partial screen sharing):

adb shell am compat enable OVERRIDE_DISABLE_MEDIA_PROJECTION_SINGLE_APP_OPTION <package>

To remove the override, which allows the app's opt out of partial screen sharing:

adb shell am compat disable OVERRIDE_DISABLE_MEDIA_PROJECTION_SINGLE_APP_OPTION <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS

Enables sending fake focus for unfocused apps in split‑screen mode. Some game engines wait to get focus before drawing the content of the app; and so, fake focus helps apps avoid staying blacked out when they are resumed and do not yet have focus.

How apps can achieve same result as override

Set property flag PROPERTY_COMPAT_ENABLE_FAKE_FOCUS to true .

How to optimize apps

You can avoid this issue if your app handles multiple orientations and configuration changes well. Enable your app to support all device form factors and app windowing modes by following the Adaptive app quality guidelines .

If you run the Unity game engine, upgrade to version 2019.4.40 or later and re‑export your game. Keep the Resizable Window option checked in the Android Player settings.

How to disable or opt out of override

Set property flag PROPERTY_COMPAT_ENABLE_FAKE_FOCUS to false .

Property flags to adjust override

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

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS <package>

To remove the override:

adb shell am compat disable OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS <package>

Note: The commands only temporarily apply or remove the override.

OVERRIDE_EXCLUDE_CAPTION_INSETS_FROM_APP_BOUNDS

When the override is enabled, the activity receives configuration that includes caption bar insets. Normally, caption bar insets are not included in the configuration.

How apps can achieve same result as override

Enable edge‑to‑edge display. See the following:

How to optimize apps

You can avoid this issue if your app enables edge‑to‑edge display.

How to disable or opt out of override

Set property flag PROPERTY_COMPAT_ALLOW_EXCLUDE_CAPTION_INSETS to false .

Property flags to adjust override

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

adb commands to test override

To apply the override:

adb shell am compat enable OVERRIDE_EXCLUDE_CAPTION_INSETS_FROM_APP_BOUNDS <package>

To remove the override:

adb shell am compat disable OVERRIDE_EXCLUDE_CAPTION_INSETS_FROM_APP_BOUNDS <package>

Note: The commands only temporarily apply or remove the override.

Дополнительные ресурсы


  1. A virtual device owner is a trusted or privileged app that manages a virtual device. Virtual device owners create virtual devices to render apps and then project the apps to remote devices, such as personal computers, virtual reality devices, or car infotainment systems. The virtual device owner is on a local device, such as a phone.