简体   繁体   English

屏幕方向锁定

[英]Screen orientation lock

Is there a reliable way to lock screen orientation on all Android devices?是否有一种可靠的方法可以在所有 Android 设备上锁定屏幕方向? The code below works for my Nexus S and other phones, but for some reason ROTATION_90 corresponds to SCREEN_ORIENTATION_REVERSE_PORTRAIT on the Xoom.下面的代码适用于我的 Nexus S 和其他手机,但由于某种原因,ROTATION_90 对应于 Xoom 上的 SCREEN_ORIENTATION_REVERSE_PORTRAIT。

Is there any way to reliably map rotation to orientation?有没有办法可靠地 map 旋转到方向?

private void lockScreenOrientation() {
    if (!mScreenOrientationLocked) {
        final int orientation = getResources().getConfiguration().orientation;
        final int rotation = getWindowManager().getDefaultDisplay().getOrientation();

        if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) {
            if (orientation == Configuration.ORIENTATION_PORTRAIT) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            }
            else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            }
        }
        else if (rotation == Surface.ROTATION_180 || rotation == Surface.ROTATION_270) {
            if (orientation == Configuration.ORIENTATION_PORTRAIT) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
            }
            else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
            }
        }

        mScreenOrientationLocked = true;
    }
}

private void unlockScreenOrientation() {
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
    mScreenOrientationLocked = false;
}

EDIT: This code is meant to get the current orientation and lock it.编辑:此代码旨在获取当前方向并将其锁定。 The orientation is locked temporarily, and then released to the user.方向被暂时锁定,然后释放给用户。

Here is my solution it works on phones and tablets in any Android SDK.这是我的解决方案,它适用于任何 Android SDK 的手机和平板电脑。

switch (getResources().getConfiguration().orientation){
        case Configuration.ORIENTATION_PORTRAIT:
            if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.FROYO){
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            } else {
                int rotation = getWindowManager().getDefaultDisplay().getRotation();
                if(rotation == android.view.Surface.ROTATION_90|| rotation == android.view.Surface.ROTATION_180){
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
                } else {
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                }
            }   
        break;

        case Configuration.ORIENTATION_LANDSCAPE:
            if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.FROYO){
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            } else {
                int rotation = getWindowManager().getDefaultDisplay().getRotation();
                if(rotation == android.view.Surface.ROTATION_0 || rotation == android.view.Surface.ROTATION_90){
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                } else {
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
                }
            }
        break;
    }

I modified diyism's answers slightly to compensate for the fact that you can't use reverse_landscape and reverse_portrait modes before version 2.3我稍微修改了 diyism 的答案,以弥补您在 2.3 版之前不能使用 reverse_landscape 和 reverse_portrait 模式的事实

private static void disableRotation(Activity activity)
{       
    final int orientation = activity.getResources().getConfiguration().orientation;
    final int rotation = activity.getWindowManager().getDefaultDisplay().getOrientation();

    // Copied from Android docs, since we don't have these values in Froyo 2.2
    int SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8;
    int SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9;

    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.FROYO)
    {
        SCREEN_ORIENTATION_REVERSE_LANDSCAPE = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
        SCREEN_ORIENTATION_REVERSE_PORTRAIT = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
    }

    if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90)
    {
        if (orientation == Configuration.ORIENTATION_PORTRAIT)
        {
            activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
        else if (orientation == Configuration.ORIENTATION_LANDSCAPE)
        {
            activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        }
    }
    else if (rotation == Surface.ROTATION_180 || rotation == Surface.ROTATION_270) 
    {
        if (orientation == Configuration.ORIENTATION_PORTRAIT) 
        {
            activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_PORTRAIT);
        }
        else if (orientation == Configuration.ORIENTATION_LANDSCAPE) 
        {
            activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
        }
    }
}

private static void enableRotation(Activity activity)
{
    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}

for a temporarily screen lock you can easily use:对于临时屏幕锁定,您可以轻松使用:

//developing for android tablets **<uses-sdk android:minSdkVersion="12" />**
//works perfectly... **WATCH OUT**: look portrait to reverse-portrait on api level 13 :)

currentActivity.setRequestedOrientation(currentActivity.getResources().getConfiguration().orientation);

//to re-enable sensor, just do:

currentActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);

used it for a temp screen lock during showing dialog and doing important background work..在显示对话框和做重要的后台工作期间将其用于临时屏幕锁定..

be sure that currentActivity is valid at the time you try to access it, otherwise it wont work:)确保 currentActivity 在您尝试访问它时有效,否则它将无法工作:)

good luck:)祝你好运:)

// Works on all devices. The other solution only works on 1/2 of the devices.
// Lock orientation
int rotation = getWindowManager().getDefaultDisplay().getRotation();
lockOrientation(rotation, Surface.ROTATION_270);
// Ensure that the rotation hasn't changed
if (getWindowManager().getDefaultDisplay().getRotation() != rotation) {
    lockOrientation(rotation, Surface.ROTATION_90);
}
// ...
private void lockOrientation(int originalRotation, int naturalOppositeRotation) {
    int orientation = getResources().getConfiguration().orientation;
    if (orientation == Configuration.ORIENTATION_PORTRAIT) {
        // Are we reverse?
        if (originalRotation == Surface.ROTATION_0 || originalRotation == naturalOppositeRotation) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        } else {
            setReversePortrait();
        }
    } else {
        // Are we reverse?
        if (originalRotation == Surface.ROTATION_0 || originalRotation == naturalOppositeRotation) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        } else {
            setReverseLandscape();
        }
    }
}

@SuppressLint("InlinedApi") 
private void setReversePortrait() {
    if (Build.VERSION.SDK_INT >= 9) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
    } else {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }
}

@SuppressLint("InlinedApi") 
private void setReverseLandscape() {
    if (Build.VERSION.SDK_INT >= 9) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
    } else {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }
}

This solution only builds on others.此解决方案仅建立在其他解决方案之上。 It is a different way to handle the problem enl8enmentnow tackled: on some devices landscape is ROTATION_90 , but on (a few) others it is ROTATION_270 .这是处理 enl8enmentnow 解决的问题的另一种方法:在某些设备上,景观是ROTATION_90 ,但在(少数)其他设备上是ROTATION_270 When I tried something like enl8enmentnow's solution on a Kindle Fire HD 7", it made the screen rotate upside down, then immediately back. I have seen no other ideas than to hard-code which devices consider landscape to be 270, so here is that hard-coded solution:当我在 Kindle Fire HD 7" 上尝试类似 enl8enmentnow 的解决方案时,它使屏幕倒转,然后立即返回。除了硬编码哪些设备认为横向为 270 之外,我没有看到其他想法,所以这就是硬编码解决方案:

public static void unlockOrientation() {

    activity.setRequestedOrientation(
        ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}

public static void lockOrientation() {

    if (Build.VERSION.SDK_INT < 18) {
        activity.setRequestedOrientation(getOrientation());
    } else {
        activity.setRequestedOrientation(
            ActivityInfo.SCREEN_ORIENTATION_LOCKED);
    }
}

private static int getOrientation() {

    int port = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
    int revP = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
    int land = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
    int revL = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
    if (Build.VERSION.SDK_INT < 9) {
        revL = land;
        revP = port;
    } else if (isLandscape270()) {
        land = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
        revL = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
    }

    Display display = activity.getWindowManager().getDefaultDisplay();
    boolean wide = activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
    switch (display.getRotation()) {
        case Surface.ROTATION_0:
            return wide ? land : port;
        case Surface.ROTATION_90:
            return wide ? land : revP;
        case Surface.ROTATION_180:
            return wide ? revL : revP;
        case Surface.ROTATION_270:
            return wide ? revL : port;
        default:
            throw new AssertionError();
    }
}

private static boolean isLandscape270() {

    return android.os.Build.MANUFACTURER.equals("Amazon")
        && !(android.os.Build.MODEL.equals("KFOT") || android.os.Build.MODEL.equals("Kindle Fire"));
}

isLandscape270() detects whether the device is a 2nd generation Kindle or later (refer to this link , getting the MODEL from this link ). isLandscape270()检测设备是否为第二代 Kindle 或更高版本(请参阅此链接,从此 链接获取MODEL )。 I do not know if other devices should also be included;我不知道是否还应该包括其他设备; please comment if you know of any.如果您知道,请发表评论。

Also, on APIs >= 18 this simply uses setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED) .此外,在 API >= 18 上,这仅使用setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED) I have only tested that on emulators;我只在模拟器上测试过; please comment if it has problems on real devices.如果在真实设备上出现问题,请发表评论。

Use: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR) because Orientation is determined by a physical orientation sensor: the display will rotate based on how the user moves the device.使用: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR)因为方向由物理方向传感器确定:显示器将根据用户移动设备的方式旋转。 This allows any of the 4 possible rotations, regardless of what the device will normally do (for example some devices won't normally use 180 degree rotation).这允许 4 种可能的旋转中的任何一种,而不管设备通常会做什么(例如,某些设备通常不会使用 180 度旋转)。 And your code should work on Xoom too...而且您的代码也应该可以在 Xoom 上运行...

You can declare an Activity as being only landscape or portrait in your AndroidManifest.xml.您可以在 AndroidManifest.xml 中将 Activity 声明为仅横向或纵向。 Just add the screenOrientation attribute to the activity element:只需将 screenOrientation 属性添加到活动元素:

http://developer.android.com/guide/topics/manifest/activity-element.html http://developer.android.com/guide/topics/manifest/activity-element.html

My solution:我的解决方案:

int orientation=act.getResources().getConfiguration().orientation;
int rotation=act.getWindowManager().getDefaultDisplay().getOrientation();
if (orientation==Configuration.ORIENTATION_PORTRAIT)
   {if (rotation==Surface.ROTATION_0 || rotation==Surface.ROTATION_270) //0 for phone, 270 for tablet
       {act.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
       }
    else
        {act.setRequestedOrientation(9);//instead of SCREEN_ORIENTATION_REVERSE_PORTRAIT when <= android 2.2
        }
   }
else
    {if (rotation==Surface.ROTATION_90 || rotation==Surface.ROTATION_0) //90 for phone, 0 for tablet
        {act.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        }
     else
         {act.setRequestedOrientation(8);//instead of SCREEN_ORIENTATION_REVERSE_LANDSCAPE when <= android 2.2
         }
    }

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

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