Le système Android ajoute un contrôle dynamique de l'orientation de l'écran et force l'application à avoir des orientations d'écran horizontales et verticales

Étapes de mise en œuvre

  • La fonction de rotation de l'écran permet aux utilisateurs de choisir l'orientation par défaut de l'écran, notamment 0 degré (portrait), 90 degrés (paysage), 180 degrés (portrait inversé) et 270 degrés (paysage inversé).
  • La fonctionnalité Forcer la rotation des applications permet aux utilisateurs de forcer toutes les applications à s'afficher en orientation paysage ou portrait, que l'application elle-même prenne en charge la rotation ou non.
  • Toutes les modifications peuvent être enregistrées après le redémarrage.Forcer la priorité de rotation de l'application > priorité de direction du système.

Modifier l'exemple

Module Rotation d'affichage

frameworks/base/services/core/java/com/android/server/wm/DisplayRotation.java

Ce module est responsable du traitement de la logique de rotation de l'écran. Une propriété système doit y être ajoutée : persist.sys.app.rotation, qui est utilisée pour contrôler respectivement les paramètres de rotation forcée de l'application et de rotation de l'écran.

Dans les méthodes rotationForOrientation() et updateOrientation(), l'orientation de l'application courante doit être modifiée en fonction de la valeur de persist.sys.app.rotation. Si c'est force_landscape, elle est forcée à être horizontale ; si c'est force_portrait , il est forcé d'être vertical ; sinon Réglez en fonction de la direction de l'application elle-même.

+++ 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.

Module Paramètres

packages/apps/Settings/res/values/arrays.xml

Ce fichier définit une liste d'options pour la rotation de l'écran et la rotation forcée des applications. Deux tableaux doivent y être ajoutés : screen_rotate_entries et screen_rotate_values, et forceapp_rotate_entries et forceapp_rotate_values.

screen_rotate_entries et screen_rotate_values ​​​​représentent respectivement le nom d'affichage et la valeur correspondante de rotation de l'écran, y compris 0 degrés, 90 degrés, 180 degrés et 270 degrés.

  • forceapp_rotate_entries et forceapp_rotate_values ​​​​représentent respectivement le nom d'affichage et la valeur correspondante de la rotation forcée de l'application, y compris la valeur par défaut, l'écran horizontal et l'écran vertical.
+++ 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>

packages/apps/Settings/res/values/strings.xml

Ce fichier définit la version anglaise de la ressource chaîne, dans laquelle il faut ajouter le titre et le résumé de la rotation de l'écran et de la rotation forcée de l'application, ainsi que la chaîne de formatage correspondante.

+++ 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>

packages/apps/Settings/res/values-zh-rCN/strings.xml

Ce fichier définit la version chinoise de la ressource chaîne, dans laquelle il faut ajouter le titre et le résumé de la rotation de l'écran et de la rotation forcée de l'application, ainsi que la chaîne de formatage correspondante.

+++ 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>

packages/apps/Settings/res/xml/display_settings.xml

Ce fichier définit la disposition de l'interface pour les paramètres d'affichage, les préférences de liste pour l'ajout de la rotation de l'écran et la rotation forcée des applications, ainsi que les valeurs clés, titres, résumés et options correspondants.

Nous utilisons les classes personnalisées ScreenRotateListPreference et ForceAppRotateListPreference pour implémenter la fonction de préférence de liste. Ces deux classes héritent de la classe RestrictedListPreference et remplacent certaines méthodes pour gérer les restrictions de l'administrateur et l'affichage des boîtes de dialogue.

+++ 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"

packages/apps/Settings/src/com/android/settings/DisplaySettings.java

Ce fichier définit le contrôleur des paramètres d'affichage, où nous devons ajouter le contrôleur de préférence de rotation de l'écran et de force de rotation de l'application, ainsi que la valeur clé et le contexte correspondants.

Utilisez les classes personnalisées ScreenRotatePreferenceController et ForceAppRotatePreferenceController pour implémenter les fonctions du contrôleur de préférences. Ces deux classes héritent de la classe AbstractPreferenceController et implémentent l'interface Preference.OnPreferenceChangeListener pour gérer les événements de changement de préférence.

+++ 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;
     }

packages/apps/Settings/src/com/android/settings/display/ScreenRotateListPreference.java

  • Ce fichier définit la classe de préférences de liste pour la rotation de l'écran, dans laquelle les fonctions suivantes doivent être implémentées :
    • Héritez de la classe RestrictedListPreference et initialisez les options et valeurs initiales dans le constructeur.
    • Remplacez la méthode onPrepareDialogBuilder() pour ajouter des vues restreintes à l'administrateur à la boîte de dialogue, le cas échéant.
    • Remplacez la méthode onDialogCreated() et ajoutez des événements de clic restreints à l'administrateur à la boîte de dialogue, le cas échéant.
    • Définissez une méthode removeUnusableRotates() pour supprimer les options indisponibles et désactiver ou activer les préférences en fonction des restrictions de l'administrateur.
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);
    }
}

packages/apps/Settings/src/com/android/settings/display/ForceAppRotateListPreference.java

  • Ce fichier définit la classe de préférences de liste qui force l'application de la rotation, et les fonctions suivantes doivent y être implémentées :
    • Héritez de la classe RestrictedListPreference et initialisez les options et valeurs initiales dans le constructeur.
    • Remplacez la méthode onPrepareDialogBuilder() pour ajouter des vues restreintes à l'administrateur à la boîte de dialogue, le cas échéant.
    • Remplacez la méthode onDialogCreated() et ajoutez des événements de clic restreints à l'administrateur à la boîte de dialogue, le cas échéant.
    • Définissez une méthode removeUnusableRotates() pour supprimer les options indisponibles et désactiver ou activer les préférences en fonction des restrictions de l'administrateur.
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.
            }
        }
    }
}

packages/apps/Settings/src/com/android/settings/display/ForceAppRotatePreferenceController.java

  • Ce fichier définit la classe du contrôleur de préférences qui force l'application de la rotation et doit y implémenter les fonctions suivantes :
    • Héritez de la classe AbstractPreferenceController et implémentez l'interface Preference.OnPreferenceChangeListener pour gérer les événements de changement de préférence.
    • Initialisez les valeurs clés et le contexte dans le constructeur.
    • Renvoie true dans la méthode isAvailable(), indiquant que le contrôleur est disponible.
    • Renvoie la valeur de la clé dans la méthode getPreferenceKey().
    • Dans la méthode updateState(), les options préférées et le résumé sont mis à jour en fonction de la valeur de la propriété système persist.sys.app.rotation.
    • Dans la méthode onPreferenceChange(), la propriété système persist.sys.app.rotation est modifiée en fonction de la valeur sélectionnée par l'utilisateur et le résumé des préférences est mis à jour.
    • Définissez une méthode getRotateDescription() pour obtenir la description correspondante en fonction de la valeur actuelle et de la liste d'options.
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);
    }
}

packages/apps/Settings/src/com/android/settings/display/ScreenRotateListPreference.java

  • Ce fichier définit la classe de préférences de liste pour la rotation de l'écran, dans laquelle les fonctions suivantes doivent être implémentées :
    • Héritez de la classe RestrictedListPreference et initialisez les options et valeurs initiales dans le constructeur.
    • Remplacez la méthode onPrepareDialogBuilder() pour ajouter des vues restreintes à l'administrateur à la boîte de dialogue, le cas échéant.
    • Remplacez la méthode onDialogCreated() et ajoutez des événements de clic restreints à l'administrateur à la boîte de dialogue, le cas échéant.
    • Définissez une méthode removeUnusableRotates() pour supprimer les options indisponibles et désactiver ou activer les préférences en fonction des restrictions de l'administrateur.
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, ce n'est pas difficile de tout ajouter ici ~

Autres enregistrements :

  1. Par exemple, pourquoi avez-vous besoin de créer cette nouvelle chose dans le fichier ForceAppRotateListPreference ? Les versions précédentes n'étaient pas si gênantes.
  2. Il y a un piège. La version AlertDialog11+ dans xxxListPreference doit être androidx.appcompat.app.AlertDialog;utilisée. La version antérieure ne peut pas être utilisée. Si deux packages sont importés en même temps, la compilation et les erreurs seront toujours signalées. Gardez-en simplement un.

Résultats de test:

insérer la description de l'image ici
insérer la description de l'image ici
Que l'application prenne ou non en charge l'écran vertical, elle sera forcée d'afficher un écran vertical.
insérer la description de l'image ici

Résumer:

Cet article décrit comment ajouter la rotation de l'écran et forcer les fonctions de rotation de l'application dans les paramètres du système Android afin que les clients puissent ajuster l'orientation de l'écran en fonction des besoins du projet.

Je suppose que tu aimes

Origine blog.csdn.net/SHH_1064994894/article/details/132568580
conseillé
Classement