简体   繁体   English

以编程方式锁定android中的方向

[英]orientation lock in android programmatically

I have the following code. 我有以下代码。

Java Java的

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

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

I am calling these functions from javascript. 我从javascript调用这些函数。 Control is entering these methods. 控制正在进入这些方法。 However the orientation is not locked. 但是方向未锁定。

I have tried following to lock the orientation 我试过跟随锁定方向

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

None of these seem to work. 这些似乎都不起作用。 Any pointers would be helpful. 任何指针都会有所帮助。

I've created a few utility methods to help deal with orientation locking, feel free to use this class. 我已经创建了一些实用方法来帮助处理方向锁定,随意使用这个类。

Example use: 使用示例:

  • In an Activity: OrientationUtils.lockOrientationPortrait(MyActivityName.this) 在活动中: OrientationUtils.lockOrientationPortrait(MyActivityName.this)
  • In a Fragment: OrientationUtils.lockOrientationLandscape(getActivity()) 在片段中: OrientationUtils.lockOrientationLandscape(getActivity())

Code: 码:

/** 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);
    }

}

Here's my full OrientationUtils class on GitHub that can be used in any Android app: https://github.com/danialgoodwin/android-simply-advanced-helper/blob/master/SimplyAdvancedHelperLibrary/src/net/simplyadvanced/utils/OrientationUtils.java 这是我在GitHub上的完整OrientationUtils类,可以在任何Android应用程序中使用: https//github.com/danialgoodwin/android-simply-advanced-helper/blob/master/SimplyAdvancedHelperLibrary/src/net/simplyadvanced/utils/OrientationUtils。 java的

Activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);


Locks the screen (activity) in whatever the orientation it was. 以任何方向锁定屏幕(活动)。

Requires API Level >= 18 需要API级别> = 18

This is a class I wrote to handle locking and unlocking the screen orientation. 这是我写的一个用来处理锁定和解锁屏幕方向的类。 I call toggleScreenOrientationLock(this, prefs, isChecked) from a toggle button's checkedChangedListener, and restoreScreenLock(this, prefs) from onCreate(). 我从切换按钮的checkedChangedListener调用toggleScreenOrientationLock(this, prefs, isChecked) ,并从onCreate()调用restoreScreenLock(this, prefs) )。 In both cases this is your activity and prefs is a SharedPrefences object, used for saving information about the state of the lock. 在这两种情况下, this都是您的活动, prefsSharedPrefences对象,用于保存有关锁状态的信息。

The complicated part pf the code is the getScreenOrientation() function, which I stole from and cleaned up from here . 代码的复杂部分是getScreenOrientation()函数, 我从这里偷走并清理了它 I'll try to explain logic behind how this works. 我将尝试解释其工作原理背后的逻辑。

When we set the device's orientation with setRequestedOrienation() , we need to know if the device is in landscape or portrait mode, and we need to know if it's a reverse orientation (rotated 180 degrees). 当我们使用setRequestedOrienation()设置设备的方向时,我们需要知道设备是处于横向还是纵向模式,我们需要知道它是否是反向(旋转180度)。

Using getResources().getConfiguration().orientation will answer the question of which orientation we're in. If we could factor in the rotation of the device, we could tell whether it was rotated 180 or not. 使用getResources().getConfiguration().orientation将回答我们所处的方向的问题。如果我们可以考虑设备的旋转,我们可以判断它是否旋转了180°。 Unfortunately, depending on the device, ROTATE_0 might be portrait or landscape. 不幸的是,根据设备的不同,ROTATE_0可能是纵向或横向。 Phones typically map ROTATE_0 to portrait, and tablets to landscape. 手机通常将ROTATE_0映射到纵向,将平板电脑映射到横向。

So the solution used here is to use the screen dimensions to determine if it is in landscape or portrait instead. 因此,此处使用的解决方案是使用屏幕尺寸来确定它是横向还是纵向。 If the screen is wider than it is tall, then we infer that the device is in a landscape orientation, and vice versa for portrait. 如果屏幕宽度超过它的高度,那么我们推断设备处于横向方向,反之亦然。 Then we can factor in the rotation to figure out whether the orientation is reversed or not. 然后我们可以考虑旋转来确定方向是否反转。

For example, if the screen is wider than it is tall, then we know we're in a landscape orientation. 例如,如果屏幕比它高,那么我们知道我们处于横向。 If the rotation is either 0 or 180 (in the code's logic, this is equal to !isRotatedOrthogonally), then we know that 0 is LANDSCAPE and 180 is REVERSE_LANDSCAPE. 如果旋转为0或180(在代码的逻辑中,这等于!isRotatedOrthogonally),那么我们知道0是LANDSCAPE,180是REVERSE_LANDSCAPE。

It has been noted elsewhere that this won't work across all devices, since whether 90 or 270 is the reversed orientation is device specific. 在其他地方已经注意到 ,这不适用于所有设备,因为90或270是反向的是设备特定的。 But this is still probably the best you're going to do; 但这仍然是你要做的最好的事情; at worst, one orientation will rotate 180 degrees when you lock it, which is what would likely happen if tried locking the screen any other way. 在最坏的情况下,当你锁定它时,一个方向将旋转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();
    }
}

Here's another simple solution that works well for me. 这是另一个适合我的简单解决方案。

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

I needed to lock orientationManager(true); 我需要锁定orientationManager(true); the current screen orientation when dialogs were opened and unlock orientationManager(false); 打开对话框时的当前屏幕方向并解锁orientationManager(false); when the dialog was closed. 对话框关闭时

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM