Android システムは画面の向きの動的な制御を追加し、APP に水平および垂直の画面の向きを強制します。

実装手順

  • 画面回転機能により、ユーザーは 0 度 (縦)、90 度 (横)、180 度 (逆縦)、270 度 (逆横) など、デフォルトの画面の向きを選択できます。
  • アプリの強制回転機能を使用すると、アプリ自体が回転をサポートしているかどうかに関係なく、ユーザーはすべてのアプリを強制的に横向きまたは縦向きに表示できます。
  • すべての変更は再起動後に保存できます。強制的に APP ローテーションの優先順位 > システムの方向の優先順位を設定します。

変更例

DisplayRotation モジュール

フレームワーク/base/services/core/java/com/android/server/wm/DisplayRotation.java

このモジュールは、画面回転のロジックの処理を担当します。システム プロパティの 1 つであるpersist.sys.app.rotation を追加する必要があります。これは、アプリケーションの強制回転と画面回転の設定をそれぞれ制御するために使用されます。

rotationForOrientation() メソッドと updateOrientation() メソッドでは、現在のアプリケーションの方向は、persist.sys.app.rotation の値に基づいて変更する必要があります。force_landscape の場合は強制的に水平になり、force_portrait の場合は強制的に水平になります。の場合は強制的に垂直になります。それ以外の場合は、アプリケーション自体の方向に従って設定されます。

+++ b/frameworks/base/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -380,6 +380,12 @@ public class DisplayRotation {
    
    
         if (newOrientation != mCurrentAppOrientation) {
    
    
             mCurrentAppOrientation = newOrientation;
             String rot = SystemProperties.get("persist.sys.app.rotation", "middle_port");
+            if (rot.equals("force_landscape")){
    
    
+                mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
+            }else if (rot.equals("force_portrait")){
    
    
+                mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
+                
+            }
             if (rot.equals("force_land") && "box".equals(SystemProperties.get("ro.target.product")))
                 mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
             if (isDefaultDisplay) {
    
    
@@ -1204,6 +1210,13 @@ public class DisplayRotation {
    
    
             Slog.v(TAG, "asx force_land :" + mLandscapeRotation);
             return mLandscapeRotation;
         }
+        
+        if (rot.equals("force_landscape")){
    
    
+            return mLandscapeRotation;
+        }else if (rot.equals("force_portrait")){
    
    
+            return mPortraitRotation;
+        }
+        
         switch (orientation) {
    
    
             case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
                 // Return portrait unless overridden.

設定モジュール

パッケージ/アプリ/設定/res/values/arrays.xml

このファイルは、画面の回転とアプリケーションの強制回転のオプションのリストを定義します。このファイルに、screen_rotate_entries と screen_rotate_values、forceapp_rotate_entries と Forceapp_rotate_values の 2 つの配列を追加する必要があります。

screen_rotate_entries と screen_rotate_values はそれぞれ、表示名と、0 度、90 度、180 度、270 度を含む画面回転の対応する値を表します。

  • Forceapp_rotate_entries と Forceapp_rotate_values はそれぞれ、デフォルト、水平画面、垂直画面を含む、アプリケーションの強制回転の表示名と対応する値を表します。
+++ b/packages/apps/Settings/res/values-zh-rCN/arrays.xml
@@ -20,6 +20,45 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    
+ 
+    <string-array name="screen_totate_entries">
+        <item>0 Degree</item>
+        <item>90 Degree</item>
+        <item>180 Degree</item>
+        <item>270 Degree</item>
+    </string-array>
+
+    <!-- Do not translate. -->
+    <string-array name="screen_rotate_values" translatable="false">
+        <!-- Do not translate. -->
+        <item>0</item>
+        <!-- Do not translate. -->
+        <item>1</item>
+        <!-- Do not translate. -->
+        <item>2</item>
+        <!-- Do not translate. -->
+        <item>3</item>
+    </string-array>
+    
+         <string-array name="forceapp_rotate_entries">
+        <item>default</item>
+        <item>portrait</item>
+        <item>landscape</item>
+
+  
+    </string-array>
+
+    <!-- Do not translate. -->
+    <string-array name="forceapp_rotate_values" translatable="false">
+        <!-- Do not translate. -->
+        <item>0</item>
+        <!-- Do not translate. -->
+        <item>1</item>
+        <!-- Do not translate. -->
+        <item>2</item>
+
+    </string-array>

パッケージ/アプリ/設定/res/values/strings.xml

このファイルは、英語版の文字列リソースを定義します。このファイルには、画面の回転とアプリケーションの強制回転のタイトルと概要、および対応する書式設定文字列を追加する必要があります。

+++ b/packages/apps/Settings/res/values/strings.xml
@@ -14,6 +14,10 @@
      limitations under the License.
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="forceapp_rotate_summary"> <xliff:g id="forceapprotate_description">%1$s</xliff:g> </string>
+    <string name="screen_rotate_summary"> <xliff:g id="screenrotate_description">%1$s</xliff:g> </string>
+    <string name="ctrl_forceapp_rotate" >"Force App Rotate"</string>
+    <string name="ctrl_screen_rotate">"Screen Rotate"</string>
     <string name="ctrl_statusbar">StatusBar</string>
     <string name="ctrl_explan">ExPlan</string>
     <string name="ctrl_navigationbar">NavigationBar</string>

パッケージ/アプリ/設定/res/values-zh-rCN/strings.xml

このファイルは、文字列リソースの中国語版を定義します。このファイルには、画面の回転とアプリケーションの強制回転のタイトルと概要、および対応する書式設定文字列を追加する必要があります。

+++ b/packages/apps/Settings/res/values-zh-rCN/strings.xml
@@ -16,6 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="forceapp_rotate_summary"> <xliff:g id="forceapprotate_description">%1$s</xliff:g> </string>
+    <string name="screen_rotate_summary"> <xliff:g id="screenrotate_description">%1$s</xliff:g> </string>
+    <string name="ctrl_forceapp_rotate" >"APP旋转"</string>
+    <string name="ctrl_screen_rotate">"屏幕旋转"</string>
     <string name="ctrl_statusbar">状态栏</string>
     <string name="ctrl_explan">下拉菜单</string>
     <string name="ctrl_navigationbar">导航栏</string>

パッケージ/アプリ/設定/res/xml/display_settings.xml

このファイルは、表示設定のインターフェイス レイアウト、画面の回転とアプリケーションの強制回転を追加するためのリストの設定、および対応するキーの値、タイトル、概要、およびオプションを定義します。

カスタム ScreenRotateListPreference クラスと ForceAppRotateListPreference クラスを使用してリスト設定機能を実装します。これら 2 つのクラスは RestrictedListPreference クラスを継承し、管理者の制限とダイアログ表示を処理するためにいくつかのメソッドをオーバーライドします。

+++ b/packages/apps/Settings/res/xml/display_settings.xml
@@ -31,7 +31,18 @@
    <SwitchPreference
        android:key="ctrl_explan"
        android:title="@string/ctrl_explan"/>
-       
+   <com.android.settings.display.ScreenRotateListPreference
+        android:key="screen_rotate"
+        android:title="@string/ctrl_screen_rotate"
+        android:summary="@string/summary_placeholder"
+        android:entries="@array/screen_rotate_entries"
+        android:entryValues="@array/screen_rotate_values"/>
+   <com.android.settings.display.ForceAppRotateListPreference 
+        android:key="forceapp_rotate"
+        android:title="@string/ctrl_forceapp_rotate"
+        android:summary="@string/summary_placeholder"
+        android:entries="@array/forceapp_rotate_entries"
+        android:entryValues="@array/forceapp_rotate_values"/>
     <com.android.settingslib.RestrictedPreference
         android:key="brightness"
         android:title="@string/brightness"

パッケージ/apps/Settings/src/com/android/settings/DisplaySettings.java

このファイルは、表示設定コントローラーを定義します。ここで、画面回転と強制アプリケーション回転設定コントローラー、および対応するキー値とコンテキストを追加する必要があります。

カスタム ScreenRotatePreferenceController クラスと ForceAppRotatePreferenceController クラスを使用して、設定コントローラーの機能を実装します。これら 2 つのクラスは、AbstractPreferenceController クラスを継承し、設定変更イベントを処理するための Preference.OnPreferenceChangeListener インターフェイスを実装します。

+++ b/packages/apps/Settings/src/com/android/settings/DisplaySettings.java
@@ -40,6 +40,8 @@ import com.android.settingslib.search.SearchIndexable;
 import com.android.settings.display.StatusBarPreferenceController;
 import com.android.settings.display.NavigationBarPreferenceController;
 import com.android.settings.display.ExPlanPreferenceController;
+import com.android.settings.display.ForceAppRotatePreferenceController;
+import com.android.settings.display.ScreenRotatePreferenceController;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -98,6 +100,8 @@ public class DisplaySettings extends DashboardFragment {
    
    
         controllers.add(new StatusBarPreferenceController(context));
         controllers.add(new NavigationBarPreferenceController(context));
         controllers.add(new ExPlanPreferenceController(context));
+        controllers.add(new ForceAppRotatePreferenceController(context,"forceapp_rotate"));
+        controllers.add(new ScreenRotatePreferenceController(context,"screen_rotate"));
         return controllers;
     }

パッケージ/apps/Settings/src/com/android/settings/display/ScreenRotateListPreference.java

  • このファイルは、画面回転用のリスト設定クラスを定義します。このクラスには、次の関数を実装する必要があります。
    • RestrictedListPreference クラスを継承し、コンストラクターで初期オプションと値を初期化します。
    • onPrepareDialogBu​​ilder() メソッドをオーバーライドして、管理者限定のビューをダイアログ ボックスに追加します (存在する場合)。
    • onDialogCreated() メソッドをオーバーライドし、管理者制限のクリック イベントをダイアログ ボックスに追加します (存在する場合)。
    • 使用できないオプションを削除し、管理者の制限に基づいて設定を無効または有効にするには、removeUnusableRotates() メソッドを定義します。
package com.android.settings.display;

import android.content.Context;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;

import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
import android.content.Intent;
import android.util.Log;
import com.android.settings.R;
import android.os.SystemProperties;
public class ScreenRotatePreferenceController extends AbstractPreferenceController implements
        PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
    
    

    private static final String TAG = "ScreenRotatePrefContr";

    /** If there is no setting in the provider, use this. */
    public static final int FALLBACK_SCREEN_ROTATE_VALUE = 0;

    private final String mScreenRotateKey;

    public ScreenRotatePreferenceController(Context context, String key) {
    
    
        super(context);
        mScreenRotateKey = key;
    }

    @Override
    public boolean isAvailable() {
    
    
        return true;
    }

    @Override
    public String getPreferenceKey() {
    
    
        return mScreenRotateKey;
    }

    @Override
    public void updateState(Preference preference) {
    
    
        final ScreenRotateListPreference screenRotateListPreference = (ScreenRotateListPreference) preference;
        long currentRotate = Settings.System.getLong(mContext.getContentResolver(),
                Settings.System.USER_ROTATION, FALLBACK_SCREEN_ROTATE_VALUE);
        screenRotateListPreference.setValue(String.valueOf(currentRotate));

        updateRotatePreferenceDescription(screenRotateListPreference, currentRotate);
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
    
    
        try {
    
    
            int value = Integer.parseInt((String) newValue);
            Settings.System.putInt(mContext.getContentResolver(), Settings.System.USER_ROTATION, value);
            updateRotatePreferenceDescription((ScreenRotateListPreference) preference, value);
        } catch (NumberFormatException e) {
    
    
            Log.e(TAG, "could not persist screen rotate setting", e);
        }
        return true;
    }

    public static CharSequence getRotateDescription(
            long currentRotate, CharSequence[] entries, CharSequence[] values) {
    
    
        if (currentRotate < 0 || entries == null || values == null
                || values.length != entries.length) {
    
    
            return null;
        }

        for (int i = 0; i < values.length; i++) {
    
    
            long rotate = Long.parseLong(values[i].toString());
            if (currentRotate == rotate) {
    
    
                return entries[i];
            }
        }
        return null;
    }

    private void updateRotatePreferenceDescription(ScreenRotateListPreference preference,
            long currentRotate) {
    
    
        final CharSequence[] entries = preference.getEntries();
        final CharSequence[] values = preference.getEntryValues();
        final String summary;

        if (preference.isDisabledByAdmin()) {
    
    
            summary = mContext.getString(com.android.settings.R.string.disabled_by_policy_title);
        } else {
    
    
            final CharSequence rotateDescription = getRotateDescription(
                    currentRotate, entries, values);
            summary = rotateDescription == null
                    ? ""
                    : mContext.getString(R.string.screen_rotate_summary, rotateDescription);
        }
        preference.setSummary(summary);
    }
}

パッケージ/apps/Settings/src/com/android/settings/display/ForceAppRotateListPreference.java

  • このファイルは、回転を強制的に適用するリスト設定クラスを定義しており、その中に次の関数を実装する必要があります。
    • RestrictedListPreference クラスを継承し、コンストラクターで初期オプションと値を初期化します。
    • onPrepareDialogBu​​ilder() メソッドをオーバーライドして、管理者限定のビューをダイアログ ボックスに追加します (存在する場合)。
    • onDialogCreated() メソッドをオーバーライドし、管理者制限のクリック イベントをダイアログ ボックスに追加します (存在する場合)。
    • 使用できないオプションを削除し、管理者の制限に基づいて設定を無効または有効にするには、removeUnusableRotates() メソッドを定義します。
package com.android.settings.display;

import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;

import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.util.Log;

import androidx.preference.Preference;

import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.core.AbstractPreferenceController;
import android.app.Dialog;
import java.util.ArrayList;
import android.view.View;
import androidx.appcompat.app.AlertDialog;

import android.util.AttributeSet;
import com.android.settings.R;
import com.android.settings.RestrictedListPreference;
import android.content.DialogInterface;

public class ForceAppRotateListPreference extends RestrictedListPreference {
    
    
    private EnforcedAdmin mAdmin;
    private final CharSequence[] mInitialEntries;
    private final CharSequence[] mInitialValues;

    public ForceAppRotateListPreference(Context context, AttributeSet attrs) {
    
    
        super(context, attrs);
        mInitialEntries = getEntries();
        mInitialValues = getEntryValues();
    }

    @Override
    protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
                                          DialogInterface.OnClickListener listener) {
    
    
        super.onPrepareDialogBuilder(builder, listener);
        if (mAdmin != null) {
    
    
            builder.setView(R.layout.admin_disabled_other_options_footer);
        } else {
    
    
            builder.setView(null);
        }
    }


    @Override
    protected void onDialogCreated(Dialog dialog) {
    
    
        super.onDialogCreated(dialog);
        dialog.create();
        if (mAdmin != null) {
    
    
            View footerView = dialog.findViewById(R.id.admin_disabled_other_options);
            footerView.findViewById(R.id.admin_more_details_link).setOnClickListener(
                    new View.OnClickListener() {
    
    
                        @Override
                        public void onClick(View view) {
    
    
                           // getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                            RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
                                    getContext(), mAdmin);
                        }
                    });
        }
    }

    public void removeUnusableRotates(long maxRotate, EnforcedAdmin admin) {
    
    
        final DevicePolicyManager dpm = (DevicePolicyManager) getContext().getSystemService(
                Context.DEVICE_POLICY_SERVICE);
        if (dpm == null) {
    
    
            return;
        }

        if (admin == null && mAdmin == null && !isDisabledByAdmin()) {
    
    
            return;
        }
        if (admin == null) {
    
    
            maxRotate = Long.MAX_VALUE;
        }

        ArrayList<CharSequence> revisedEntries = new ArrayList<CharSequence>();
        ArrayList<CharSequence> revisedValues = new ArrayList<CharSequence>();
        for (int i = 0; i < mInitialValues.length; ++i) {
    
    
            long rotate = Long.parseLong(mInitialValues[i].toString());
            if (rotate <= maxRotate) {
    
    
                revisedEntries.add(mInitialEntries[i]);
                revisedValues.add(mInitialValues[i]);
            }
        }

        // If there are no possible options for the user, then set this preference as disabled
        // by admin, otherwise remove the padlock in case it was set earlier.
        if (revisedValues.size() == 0) {
    
    
            setDisabledByAdmin(admin);
            return;
        } else {
    
    
            setDisabledByAdmin(null);
        }

        if (revisedEntries.size() != getEntries().length) {
    
    
            final int userPreference = Integer.parseInt(getValue());
            setEntries(revisedEntries.toArray(new CharSequence[0]));
            setEntryValues(revisedValues.toArray(new CharSequence[0]));
            mAdmin = admin;
            if (userPreference <= maxRotate) {
    
    
                setValue(String.valueOf(userPreference));
            } else if (revisedValues.size() > 0
                    && Long.parseLong(revisedValues.get(revisedValues.size() - 1).toString())
                            == maxRotate) {
    
    
                // If the last one happens to be the same as the max rotate, select that
                setValue(String.valueOf(maxRotate));
            } else {
    
    
                // There will be no highlighted selection since nothing in the list matches
                // maxRotate. The user can still select anything less than maxRotate.
                // TODO: maybe append maxRotate to the list and mark selected.
            }
        }
    }
}

パッケージ/apps/Settings/src/com/android/settings/display/ForceAppRotatePreferenceController.java

  • このファイルは、回転の適用を強制する設定コントローラー クラスを定義し、その中に次の関数を実装する必要があります。
    • AbstractPreferenceController クラスを継承し、Preference.OnPreferenceChangeListener インターフェイスを実装して、設定変更イベントを処理します。
    • コンストラクターでキー値とコンテキストを初期化します。
    • isAvailable() メソッドで true を返し、コントローラーが使用可能であることを示します。
    • getPreferenceKey() メソッドでキー値を返します。
    • updateState() メソッドでは、システム プロパティpersist.sys.app.rotation の値に基づいて、優先オプションと概要が更新されます。
    • onPreferenceChange() メソッドでは、ユーザーが選択した値に基づいてシステム プロパティpersist.sys.app.rotation が変更され、設定の概要が更新されます。
    • getRotateDescription() メソッドを定義して、現在の値とオプション リストに基づいて対応する説明を取得します。
package com.android.settings.display;

import android.content.Context;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;

import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
import android.content.Intent;
import android.util.Log;
import com.android.settings.R;
import android.os.SystemProperties;
public class ScreenRotatePreferenceController extends AbstractPreferenceController implements
        PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
    
    

    private static final String TAG = "ScreenRotatePrefContr";

    /** If there is no setting in the provider, use this. */
    public static final int FALLBACK_SCREEN_ROTATE_VALUE = 0;

    private final String mScreenRotateKey;

    public ScreenRotatePreferenceController(Context context, String key) {
    
    
        super(context);
        mScreenRotateKey = key;
    }

    @Override
    public boolean isAvailable() {
    
    
        return true;
    }

    @Override
    public String getPreferenceKey() {
    
    
        return mScreenRotateKey;
    }

    @Override
    public void updateState(Preference preference) {
    
    
        final ScreenRotateListPreference screenRotateListPreference = (ScreenRotateListPreference) preference;
        long currentRotate = Settings.System.getLong(mContext.getContentResolver(),
                Settings.System.USER_ROTATION, FALLBACK_SCREEN_ROTATE_VALUE);
        screenRotateListPreference.setValue(String.valueOf(currentRotate));

        updateRotatePreferenceDescription(screenRotateListPreference, currentRotate);
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
    
    
        try {
    
    
            int value = Integer.parseInt((String) newValue);
            Settings.System.putInt(mContext.getContentResolver(), Settings.System.USER_ROTATION, value);
            updateRotatePreferenceDescription((ScreenRotateListPreference) preference, value);
        } catch (NumberFormatException e) {
            Log.e(TAG, "could not persist screen rotate setting", e);
        }
        return true;
    }

    public static CharSequence getRotateDescription(
            long currentRotate, CharSequence[] entries, CharSequence[] values) {
        if (currentRotate < 0 || entries == null || values == null
                || values.length != entries.length) {
            return null;
        }

        for (int i = 0; i < values.length; i++) {
            long rotate = Long.parseLong(values[i].toString());
            if (currentRotate == rotate) {
    
    
                return entries[i];
            }
        }
        return null;
    }

    private void updateRotatePreferenceDescription(ScreenRotateListPreference preference,
            long currentRotate) {
    
    
        final CharSequence[] entries = preference.getEntries();
        final CharSequence[] values = preference.getEntryValues();
        final String summary;

        if (preference.isDisabledByAdmin()) {
    
    
            summary = mContext.getString(com.android.settings.R.string.disabled_by_policy_title);
        } else {
    
    
            final CharSequence rotateDescription = getRotateDescription(
                    currentRotate, entries, values);
            summary = rotateDescription == null
                    ? ""
                    : mContext.getString(R.string.screen_rotate_summary, rotateDescription);
        }
        preference.setSummary(summary);
    }
}

パッケージ/apps/Settings/src/com/android/settings/display/ScreenRotateListPreference.java

  • このファイルは、画面回転用のリスト設定クラスを定義します。このクラスには、次の関数を実装する必要があります。
    • RestrictedListPreference クラスを継承し、コンストラクターで初期オプションと値を初期化します。
    • onPrepareDialogBu​​ilder() メソッドをオーバーライドして、管理者限定のビューをダイアログ ボックスに追加します (存在する場合)。
    • onDialogCreated() メソッドをオーバーライドし、管理者制限のクリック イベントをダイアログ ボックスに追加します (存在する場合)。
    • 使用できないオプションを削除し、管理者の制限に基づいて設定を無効または有効にするには、removeUnusableRotates() メソッドを定義します。
package com.android.settings.display;

import android.content.Context;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;

import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
import android.content.Intent;
import android.util.Log;
import com.android.settings.R;
import android.os.SystemProperties;
public class ForceAppRotatePreferenceController extends AbstractPreferenceController implements
        PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
    
    

    private static final String TAG = "ForceAppRotatePrefContr";

    /** If there is no setting in the provider, use this. */
    public static final int FALLBACK_FORCE_APP_ROTATE_VALUE = 0;

    private final String mForceAppRotateKey;

    public ForceAppRotatePreferenceController(Context context, String key) {
    
    
        super(context);
        mForceAppRotateKey = key;
    }

    @Override
    public boolean isAvailable() {
    
    
        return true;
    }

    @Override
    public String getPreferenceKey() {
    
    
        return mForceAppRotateKey;
    }

    @Override
    public void updateState(Preference preference) {
    
    
        final ForceAppRotateListPreference forceAppRotateListPreference = (ForceAppRotateListPreference) preference;
        long currentRotate = 0;
        String rot = SystemProperties.get("persist.sys.app.rotation", "middle_port");
        if (rot.equals("force_landscape")){
    
    
            currentRotate = 1;
        }else if (rot.equals("force_portrait")){
    
    
            currentRotate = 2;
        }else{
    
    
            currentRotate = 0;
        }
        
        forceAppRotateListPreference.setValue(String.valueOf(currentRotate));

        updateRotatePreferenceDescription(forceAppRotateListPreference, currentRotate);
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
    
    
        try {
    
    
            int value = Integer.parseInt((String) newValue);
            if(value==0){    
                SystemProperties.set("persist.sys.app.rotation", "");
            }else if (value==1){
                SystemProperties.set("persist.sys.app.rotation", "force_portrait");
            }else if (value==2){
                SystemProperties.set("persist.sys.app.rotation", "force_landscape");
            }
            //Settings.System.putInt(mContext.getContentResolver(), "FORCE_APP_ROTATION", value);
            updateRotatePreferenceDescription((ForceAppRotateListPreference) preference, value);
        } catch (NumberFormatException e) {
            Log.e(TAG, "could not persist force app rotate setting", e);
        }
        return true;
    }

    public static CharSequence getRotateDescription(
            long currentRotate, CharSequence[] entries, CharSequence[] values) {
        if (currentRotate < 0 || entries == null || values == null
                || values.length != entries.length) {
            return null;
        }

        for (int i = 0; i < values.length; i++) {
            long rotate = Long.parseLong(values[i].toString());
            if (currentRotate == rotate) {
    
    
                return entries[i];
            }
        }
        return null;
    }

    private void updateRotatePreferenceDescription(ForceAppRotateListPreference preference,
            long currentRotate) {
    
    
        final CharSequence[] entries = preference.getEntries();
        final CharSequence[] values = preference.getEntryValues();
        final String summary;

        if (preference.isDisabledByAdmin()) {
    
    
            summary = mContext.getString(com.android.settings.R.string.disabled_by_policy_title);
        } else {
    
    
            final CharSequence rotateDescription = getRotateDescription(
                    currentRotate, entries, values);
            summary = rotateDescription == null
                    ? ""
                    : mContext.getString(R.string.forceapp_rotate_summary, rotateDescription);
        }
        preference.setSummary(summary);
    }
}

OK、ここにすべてを追加するのは難しくありません~

その他の記録:

  1. たとえば、なぜ ForceAppRotateListPreference ファイルにこの新しいものを作成する必要があるのでしょうか? 以前のバージョンではそれほど面倒ではありませんでした。
  2. 落とし穴があります。xxxListPreference の AlertDialog11+ バージョンをandroidx.appcompat.app.AlertDialog;使用する必要があります。以前のバージョンは使用できません。2 つのパッケージを同時にインポートすると、コンパイルとエラーが常に報告されます。1 つだけ保持してください。

試験結果:

ここに画像の説明を挿入します
ここに画像の説明を挿入します
アプリケーションが縦画面をサポートしているかどうかに関係なく、強制的に縦画面になります。
ここに画像の説明を挿入します

要約:

この記事では、顧客がプロジェクトのニーズに応じて画面の向きを調整できるように、Android システム設定で画面の回転を追加し、アプリ アプリケーションの回転機能を強制する方法について説明します。

おすすめ

転載: blog.csdn.net/SHH_1064994894/article/details/132568580