Ustawienie automatycznego obracania oparte na stanie urządzenia

W przypadku urządzeń składanych można zoptymalizować komfort użytkowania, dostosowując zachowanie obrotu ekranu do fizycznego stanu urządzenia. Możesz na przykład ustawić automatyczne obracanie ekranu po rozłożeniu urządzenia w trybie tabletu, ale zablokować je w orientacji pionowej, gdy urządzenie jest złożone.

Od Androida 13 system ten może dostosowywać ustawienia autoobracania na podstawie stanu urządzenia, np. złożonego, rozłożonego lub częściowo złożonego (tryb stołowy).

Strona ustawień autoobracania w zależności od stanu urządzenia

Ilustracja 1. Ustawienia autoobracania na podstawie stanu urządzenia widoczne dla użytkownika.

Włączanie automatycznego obracania na podstawie stanu urządzenia

Aby włączyć i skonfigurować automatyczne obracanie na podstawie stanu urządzenia, utwórz nakładkę urządzenia dla pliku config.xml platformy w ten sposób:

  1. Skonfiguruj domyślne zachowanie autoobracania dla różnych pozycji urządzenia, wypełniając tablicę liczb całkowitych [config_perDeviceStateRotationLockDefaults][7] w nakładce urządzenia 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 to odwołanie do innego stanu urządzenia. Musisz określić, kiedy wartość stanu to Settings.Secure.DEVICE_STATE_ROTATION_LOCK_IGNORED. Gdy pozycja jest skonfigurowana w ten sposób, wszystkie żądania pobrania lub ustawienia preferencji autoobracania są przekierowywane do pozycji rezerwowej.

    Jeśli na przykład postawa HALF_OPENED powróci do postawy OPENED:

    • Odczytanie ustawienia autoobracania dla HALF_OPENED zwraca bieżące ustawienie dla OPENED.
    • Zapisanie nowych preferencji autoobracania, gdy urządzenie jest w pozycji HALF_OPENED, aktualizuje preferencje dla pozycji OPENED.
  2. Skonfiguruj opisy dla każdej pozycji urządzenia, którą może ustawić użytkownik. Wypełnij tablicę tekstowąconfig_settableAutoRotationDeviceStatesDescriptions w nakładce aplikacji Ustawienia na urządzeniu:

    <!-- 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. Aby zapobiec niespójnemu działaniu, musisz używać odpowiednich interfejsów API do programowego modyfikowania tych ustawień, a nie bezpośrednio zapisywać ich u dostawców ustawień:

    • Aby zmienić bieżący stan blokady obrotu (modyfikuje ACCELEROMETER_ROTATION):

      • W interfejsie SystemUI lub Menu z aplikacjami użyj [RotationPolicy#setRotationLock(...)][5].
      • W Menedżerze okien użyj DisplayRotation#freezeRotation() lub thawRotation().
    • Aby zmienić ustawienie blokady obrotu dla określonego stanu urządzenia (zmienia DEVICE_STATE_ROTATION_LOCK):

      • Użyj właściwości requestDeviceStateAutoRotateSettingChange(...)RotationPolicy lub [DeviceStateAutoRotateSettingManager][6].

Szczegóły implementacji

Ustawienia i klasy kluczy podstawowych, które kontrolują zachowanie automatycznego obracania na urządzeniu składanym, opisano w sekcjach poniżej.

Ustawienia

System używa tych 2 ustawień do zarządzania autoobracaniem:

  • Settings.System.ACCELEROMETER_ROTATION: to główne ustawienie autoobracania. W przypadku urządzenia składanego wartość ta odzwierciedla, czy autoobracanie jest włączone dla bieżącej pozycji urządzenia.

  • Settings.Secure.DEVICE_STATE_ROTATION_LOCK: to ustawienie przechowuje preferencje użytkownika dotyczące autoobracania dla każdej pozycji urządzenia (np. złożonej lub rozłożonej). Dzięki temu system może zastosować odpowiednie ustawienie, gdy zmieni się położenie urządzenia.

    Ustawienie jest przechowywane jako ciąg znaków rozdzielony dwukropkami. Każda para wartości reprezentuje pozycję urządzenia i odpowiadające jej ustawienie obrotu. Format to:

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

    Wartości rotacji to:

    • 0: ignorowane (używane jest ustawienie pozycji rezerwowej)
    • 1: Zablokowany (autoobracanie jest wyłączone)
    • 2: odblokowany (autoobracanie jest włączone)

    Na przykład ciąg znaków "0:2:2:1" oznacza:

    • W przypadku złożonego urządzenia (pozycja 0) autoobracanie jest odblokowane (2).
    • W przypadku rozłożonego urządzenia (pozycja 2) autoobracanie jest zablokowane (1).

Kluczowe klasy

Logika zarządzania ustawieniami autoobracania na podstawie stanu urządzenia jest obsługiwana przez te klasy:

  • [DeviceStateAutoRotateSettingManagerImpl][1]: Zarządza ustawieniem DEVICE_STATE_ROTATION_LOCK. Umożliwia aktualizowanie ustawienia, pobieranie jego wartości i rejestrowanie odbiorców zmian.

  • [DeviceStateAutoRotateSettingController (Menedżer okien)][2]: synchronizuje ACCELEROMETER_ROTATIONDEVICE_STATE_ROTATION_LOCK. Gdy zmieni się położenie urządzenia, ACCELEROMETER_ROTATION zostanie zaktualizowany zgodnie z preferencjami użytkownika dotyczącymi nowego stanu. Dzięki temu każda zmiana w ACCELEROMETER_ROTATION jest zapisywana z powrotem w DEVICE_STATE_ROTATION_LOCK w przypadku bieżącego stanu urządzenia, a zmiany w DEVICE_STATE_ROTATION_LOCK w przypadku bieżącego stanu są odzwierciedlane w ACCELEROMETER_ROTATION.

  • [DeviceStateAutoRotateSettingController (Aplikacja Ustawienia)][3]: sterowanie interfejsem na stronie ustawień autoobracania w zależności od stanu urządzenia.

  • PostureDeviceStateConverter: konwertuje ogólne identyfikatory stanu urządzenia na identyfikatory pozycji urządzenia używane przez tę funkcję.

Weryfikacja

Działanie tej funkcji jest w dużej mierze uzależnione od konfiguracji OEM, dlatego nie ma dla niej konkretnych testów CTS. Musisz przeprowadzić testy ręczne, aby sprawdzić, czy ustawienia autoobracania zmieniają się zgodnie z oczekiwaniami, gdy urządzenie przechodzi między różnymi skonfigurowanymi stanami fizycznymi.

[1] https://cs.android.com/android/platform/superproject/+/android-latest-release:frameworks/base/packages/SettingsLib/DeviceStateRotationLock/src/com/android/settingslib/devicestate/DeviceStateAutoRotateSettingManagerImpl.java [2] https://cs.android.com/android/platform/superproject/+/android-latest-release:frameworks/base/services/core/java/com/android/server/wm/DeviceStateAutoRotateSettingController.java [3] https://cs.android.com/android/platform/superproject/+/android-latest-release:packages/apps/Settings/src/com/android/settings/display/DeviceStateAutoRotateSettingController.java [4] https://cs.android.com/android/platform/superproject/+/android-latest-release:frameworks/base/core/java/android/provider/Settings.java [5] https://cs.android.com/android/platform/superproject/+/android-latest-release:frameworks/base/core/java/com/android/internal/view/RotationPolicy.java;bpv=0 [6] https://cs.android.com/android/platform/superproject/+/android-latest-release:frameworks/base/packages/SettingsLib/DeviceStateRotationLock/src/com/android/settingslib/devicestate/DeviceStateAutoRotateSettingManager.java [7] https://cs.android.com/android/platform/superproject/+/android-latest-release:packages/apps/Settings/res/values/config.xml;l=674;drc=485b59a37c1cd0af72ca706e0ba1094f4e7fef0e;l=674