在Android中以编程方式实现屏幕方向锁定

11

我有以下的代码。

Java

public void lockScreenOrientation() {
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
}

public void unlockScreenOrientation() {
     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}

我正在从javascript调用这些函数。程序正在进入这些方法,但方向没有被锁定。

我尝试了以下方法来锁定方向

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);

这些方法似乎都不起作用。有任何提示将会很有帮助。


你尝试过使用 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); 吗? - MysticMagicϡ
1
你需要哪种方向模式? - GrIsHu
我想锁定屏幕方向。如果是横屏,我要锁定横屏;如果是竖屏,我想锁定竖屏。但两者都不起作用。因此,我正在尝试为测试目的将其锁定为横屏模式。 - user2682527
尝试在设定内容视图之前使用try setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);然后,在设置完内容视图后使用setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);。 - Bharat Sharma
尝试了所有这些 - ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR,ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED,ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE。 - user2682527
@user2682527 请查看我的回答。 - GrIsHu
4个回答

14
Activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);


无论屏幕(活动)的方向如何,都会锁定屏幕。

要求API Level >= 18


8
我已经创建了一些实用方法来帮助处理方向锁定,欢迎使用这个类。
使用示例:
  • 在Activity中:OrientationUtils.lockOrientationPortrait(MyActivityName.this)
  • 在Fragment中:OrientationUtils.lockOrientationLandscape(getActivity())
代码:
/** Static methods related to device orientation. */
public class OrientationUtils {
    private OrientationUtils() {}

    /** Locks the device window in landscape mode. */
    public static void lockOrientationLandscape(Activity activity) {
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }

    /** Locks the device window in portrait mode. */
    public static void lockOrientationPortrait(Activity activity) {
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    /** Allows user to freely use portrait or landscape mode. */
    public static void unlockOrientation(Activity activity) {
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
    }

}

这是我在GitHub上的完整OrientationUtils类,可在任何Android应用中使用:https://github.com/danialgoodwin/android-simply-advanced-helper/blob/master/SimplyAdvancedHelperLibrary/src/net/simplyadvanced/utils/OrientationUtils.java

说明:该类可以帮助应用开发者轻松处理横竖屏切换、旋转等操作,有助于提高用户体验。


1

这是另一个对我很有效的简单解决方案。

private void orientationManager(boolean lock)
{
    int currentOrientation = getResources().getConfiguration().orientation;
    if(lock)
    {
        if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE)
        {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
        }
        else
        {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
        }
    }
    else
    {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
    }
}

当打开对话框时,我需要锁定当前屏幕方向 orientationManager(true); ,并在关闭对话框时解锁 orientationManager(false);


1
这是我编写的一个处理屏幕方向锁定和解锁的类。我从切换按钮的checkedChangedListener中调用toggleScreenOrientationLock(this, prefs, isChecked),并从onCreate()中调用restoreScreenLock(this, prefs)。在两种情况下,this是您的活动,而prefs是一个SharedPrefences对象,用于保存有关锁定状态的信息。
代码中复杂的部分是getScreenOrientation()函数,我从这里借鉴并进行了清理。我将尝试解释它的工作逻辑。
当我们使用setRequestedOrienation()设置设备的方向时,我们需要知道设备是否处于横向或纵向模式,并且需要知道它是否是反向方向(旋转180度)。
使用getResources().getConfiguration().orientation可以回答我们所处的方向。如果我们能考虑设备的旋转,我们就可以知道它是否旋转了180度。不幸的是,根据设备的不同,ROTATE_0可能是纵向或横向的。手机通常将ROTATE_0映射到纵向,而平板电脑则映射到横向。
因此,在这里使用屏幕尺寸来确定它是横向还是纵向。如果屏幕比高度宽,则我们推断设备处于横向方向,反之亦然。然后我们可以考虑旋转来确定方向是否被反转。
例如,如果屏幕比高度宽,则我们知道我们处于横向方向。如果旋转角度为0或180(在代码逻辑中,这等于!isRotatedOrthogonally),则我们知道0是LANDSCAPE,而180是REVERSE_LANDSCAPE。

在其他地方已经注意到,这种方法不适用于所有设备,因为90度或270度的反转方向是特定于设备的。但这可能仍然是你能做的最好的方法;最坏的情况下,一个方向会在锁定时旋转180度,如果尝试以其他方式锁定屏幕,则很可能会发生这种情况。

public class ScreenLocker {
    final private static String ROTATION_LOCKED_KEY = "LockedOrientationVal";
    final private static String ROTATION_IS_LOCKED_KEY = "IsRotationLocked";
    final private static String ROTATION_SAVED_KEY = "SavedOrientationVal";

    public static int getScreenOrientation(Activity activity) {
        final Display display = activity.getWindowManager().getDefaultDisplay();
        final int rotation = display.getRotation();

        Point size = new Point();
        display.getSize(size);

        final boolean isWiderThanTall = size.x > size.y;

        final boolean isRotatedOrthogonally = (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270);
        int orientation;

        if (isRotatedOrthogonally) {
            if (isWiderThanTall)
                orientation = (rotation ==  Surface.ROTATION_90) ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
            else
                orientation = (rotation == Surface.ROTATION_90) ? ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; // normal and reversed switched intended
        }
        else {
            if (isWiderThanTall)
                orientation = (rotation ==  Surface.ROTATION_0) ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
            else
                orientation = (rotation == Surface.ROTATION_0) ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
        }

        return orientation;
    }

    public static void toggleScreenOrientationLock(Activity activity,SharedPreferences prefs, boolean lock) {
        if(lock)
            lockScreenOrientation(activity, prefs);
        else
            unlockScreenOrientation(activity, prefs);
    }


    // call this from your activity's onCreate() or onResume()
    public static boolean restoreScreenLock(Activity activity, SharedPreferences prefs) {
        final boolean isLocked = prefs.getBoolean(ROTATION_IS_LOCKED_KEY, false);
        final int previousLockedOrientation = prefs.getInt(ROTATION_LOCKED_KEY, -999);

        if(isLocked && previousLockedOrientation != -999) {
            prefs.edit().putInt(ROTATION_SAVED_KEY, activity.getRequestedOrientation()).apply();
            activity.setRequestedOrientation(previousLockedOrientation);
            return true;
        }
        return false;
    }

    private static void lockScreenOrientation(Activity activity, SharedPreferences prefs) {
        final int currentOrientation = activity.getRequestedOrientation();
        final int lockOrientation = getScreenOrientation(activity);

        // checking isCurrentlyLocked prevents the ROTATION_LOCKED_KEY and ROTATION_SAVED_KEY
        // becoming identical, which results in the screen not being able to be unlocked.
        final boolean isCurrentlyLocked = prefs.getBoolean(ROTATION_IS_LOCKED_KEY, false);

        if(!isCurrentlyLocked) {
            activity.setRequestedOrientation(lockOrientation);
            prefs.edit()
                    .putInt(ROTATION_SAVED_KEY, currentOrientation)
                    .putInt(ROTATION_LOCKED_KEY, lockOrientation)
                    .putBoolean(ROTATION_IS_LOCKED_KEY, true)
                    .apply();
        }
    }

    private static void unlockScreenOrientation(Activity activity, SharedPreferences prefs) {
        final int savedOrientation = prefs.getInt(ROTATION_SAVED_KEY, activity.getRequestedOrientation());
        activity.setRequestedOrientation(savedOrientation);
        prefs.edit().putBoolean(ROTATION_IS_LOCKED_KEY, false).apply();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接