Настройка автоматического поворота на основе состояния устройства

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

Начиная с Android 13, в Android появилась возможность настраивать параметры автоматического поворота в зависимости от состояния устройства, например, сложено, разложено или сложено наполовину (настольный режим).

Страница настроек автоматического поворота на основе состояния устройства

Рисунок 1: Настройки автоматического поворота на основе состояния устройства, видимые пользователю.

Включить настройку автоматического поворота на основе состояния устройства

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

  1. Настройте поведение автоматического поворота по умолчанию для различных положений устройства, заполнив целочисленный массив config_perDeviceStateRotationLockDefaults в файле config.xml наложения вашего устройства:

    <!-- In your device overlay, for example,
        device/generic/goldfish/phone/overlay/frameworks/base/core/res/res/values/config.xml -->
    <resources>
        <!-- Map of device posture to rotation lock setting. Each entry must be
            in the format "key:value", or "key:value:fallback_key" for example:
            "0:1" or "2:0:1". The keys are one of
            Settings.Secure.DeviceStateRotationLockKey, and the values are one of
            Settings.Secure.DeviceStateRotationLockSetting. -->
        <integer-array name="config_perDeviceStateRotationLockDefaults">
            <item>0:1</item> <!-- CLOSED -> LOCKED -->
            <item>1:0:2</item> <!-- HALF_OPENED -> IGNORED and fallback to
                device posture OPENED -->
            <item>2:2</item> <!-- OPENED -> UNLOCKED -->
            <item>3:0:0</item> <!-- REAR_DISPLAY -> IGNORED and fallback to
                device posture CLOSED -->
        </integer-array>
    </resources>
    

    fallback-key — это ссылка на другое состояние устройства, и необходимо указать, когда значение состояния — Settings.Secure.DEVICE_STATE_ROTATION_LOCK_IGNORED . Если состояние настроено таким образом, любые запросы на получение или установку параметра автоматического поворота перенаправляются в резервное состояние.

    Например, если поза HALF_OPENED возвращается в позу OPENED :

    • Чтение настройки автоматического поворота для HALF_OPENED возвращает текущую настройку для OPENED .
    • Запись нового параметра автоматического поворота, когда устройство находится HALF_OPENED обновляет параметр для положения OPENED .
  2. Настройте описания для каждого положения устройства, настраиваемого пользователем. Заполните массив строк config_settableAutoRotationDeviceStatesDescriptions в приложении «Настройки» вашего устройства:

    <!-- In your device's Settings app overlay -->
    <resources>
        <!-- The settings/preference description for each settable device
            posture defined in the array
            "config_perDeviceStateRotationLockDefaults".
            The item in position "i" describes the auto-rotation setting for the
            device posture also in position "i" in the array
            "config_perDeviceStateRotationLockDefaults". -->
        <string-array name="config_settableAutoRotationDeviceStatesDescriptions">
            <item>Auto-rotate when folded</item>
            <item>@null</item> <!-- No description for state in position 1 (it
            is not settable by the user) -->
            <item>Auto-rotate when unfolded</item>
        </string-array>
    </resources>
    
  3. Для предотвращения несогласованного поведения необходимо использовать правильные API для программного изменения этих настроек, а не писать напрямую поставщикам настроек:

    • Чтобы изменить текущее состояние блокировки вращения (изменяет ACCELEROMETER_ROTATION ):

      • Из SystemUI или Launcher используйте RotationPolicy#setRotationLock(...) .
      • В диспетчере окон используйте DisplayRotation#freezeRotation() или thawRotation() .
    • Чтобы изменить настройки блокировки вращения для определенного состояния устройства (изменяет DEVICE_STATE_ROTATION_LOCK ):

Подробности реализации

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

Настройки

Для управления автоповоротом система использует следующие две настройки:

  • Settings.System.ACCELEROMETER_ROTATION : Это основной параметр автоповорота. Для складного устройства его значение определяет, включен ли автоповорот в текущем положении устройства.

  • Settings.Secure.DEVICE_STATE_ROTATION_LOCK : этот параметр сохраняет настройки автоматического поворота, заданные пользователем для каждого положения устройства (например, сложенного или разложенного). Это позволяет системе применять правильные настройки при изменении положения устройства.

    Параметр хранится в виде строки, разделённой двоеточиями. Каждая пара значений представляет собой положение устройства и соответствующий ему параметр поворота. Формат:

    <device_posture_0>:<rotation_value_0>:<device_posture_1>:<rotation_value_1>...

    Значения для вращения следующие:

    • 0 : Игнорируется (используется настройка для резервной позы)
    • 1 : Заблокировано (автоматический поворот отключен)
    • 2 : Разблокировано (автоповорот включен)

    Например, строка "0:2:2:1" означает:

    • В сложенном состоянии (положение 0 ) автоматический поворот разблокирован ( 2 ).
    • В разложенном состоянии (положение 2 ) автоматический поворот заблокирован ( 1 ).

Ключевые классы

Логика управления настройками автоматического поворота на основе состояния устройства обрабатывается следующими классами:

  • DeviceStateAutoRotateSettingManagerImpl : управляет параметром DEVICE_STATE_ROTATION_LOCK . Он предоставляет методы для обновления параметра, получения его значения и регистрации прослушивателей изменений.

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

  • DeviceStateAutoRotateSettingController (приложение «Настройки») : управление пользовательским интерфейсом на странице настроек автоматического поворота на основе состояния устройства.

  • PostureDeviceStateConverter : выполняет преобразование между общими идентификаторами состояния устройства и идентификаторами положения устройства, используемыми этой функцией.

Проверка

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