【问题标题】:How do I get the CURRENT orientation (ActivityInfo.SCREEN_ORIENTATION_*) of an Android device?如何获取 Android 设备的当前方向 (ActivityInfo.SCREEN_ORIENTATION_*)?
【发布时间】:2012-04-30 09:02:59
【问题描述】:

我想了解设备的详细方向,最好是ActivityInfo 中的SCREEN_ORIENTATION_LANDSCAPESCREEN_ORIENTATION_PORTRAITSCREEN_ORIENTATION_REVERSE_LANDSCAPESCREEN_ORIENTATION_REVERSE_PORTRAIT 或同等设备之一。

包括 StackOverflow 上的一些答案

getWindowManager().getDefaultDisplay().getRotation()

但这并不能真正告诉我设备是处于纵向还是横向模式,只能告诉我它是如何参照其自然位置转动的——它首先可以是横向或纵向。

getResources().getConfiguration().orientation

返回以下三个之一:ORIENTATION_LANDSCAPEORIENTATION_PORTRAITORIENTATION_SQUARE,这并不能真正告诉我手机是朝哪个方向转动的(无论是倒置还是转向哪一侧) .

我知道我可以将后者与DisplayMetrics 结合使用来找出设备的自然方向,但真的没有更好的方法吗?

【问题讨论】:

    标签: android screen-orientation


    【解决方案1】:

    我最终使用了以下解决方案:

    private int getScreenOrientation() {
        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int width = dm.widthPixels;
        int height = dm.heightPixels;
        int orientation;
        // if the device's natural orientation is portrait:
        if ((rotation == Surface.ROTATION_0
                || rotation == Surface.ROTATION_180) && height > width ||
            (rotation == Surface.ROTATION_90
                || rotation == Surface.ROTATION_270) && width > height) {
            switch(rotation) {
                case Surface.ROTATION_0:
                    orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
                    break;
                case Surface.ROTATION_90:
                    orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
                    break;
                case Surface.ROTATION_180:
                    orientation =
                        ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
                    break;
                case Surface.ROTATION_270:
                    orientation =
                        ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
                    break;
                default:
                    Log.e(TAG, "Unknown screen orientation. Defaulting to " +
                            "portrait.");
                    orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
                    break;              
            }
        }
        // if the device's natural orientation is landscape or if the device
        // is square:
        else {
            switch(rotation) {
                case Surface.ROTATION_0:
                    orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
                    break;
                case Surface.ROTATION_90:
                    orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
                    break;
                case Surface.ROTATION_180:
                    orientation =
                        ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
                    break;
                case Surface.ROTATION_270:
                    orientation =
                        ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
                    break;
                default:
                    Log.e(TAG, "Unknown screen orientation. Defaulting to " +
                            "landscape.");
                    orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
                    break;              
            }
        }
    
        return orientation;
    }
    

    注意:一些用户(以下 cmets 中的 Geltrude 和 holtaf)指出,此解决方案不适用于所有设备,因为从自然方向旋转的方向未标准化。

    【讨论】:

    • 太棒了!非常感谢!
    • 如果您的活动具有固定的屏幕方向,这将失败。 getRotation 仅在屏幕方向未锁定时报告一个值。
    • 很公平,但是如果您锁定了屏幕方向,那么您很可能知道它是锁定为横向还是纵向 - 因此您不需要此代码来弄清楚。
    • 适合我的大多数用户,Xperia Tablet Z 会失败
    • 当您需要确定从相机意图捕获的图像旋转到哪个方向时,这非常棒...... Android 很糟糕。
    【解决方案2】:

    简单的方法是使用

    getResources().getConfiguration().orientation
    

    1 代表肖像,2 代表风景。

    【讨论】:

    • 该问题要求提供更详细的信息,即包括反向纵向和反向横向,这些功能不提供。
    【解决方案3】:
    public static int getScreenOrientation(Activity activity) {
            int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
            int orientation = activity.getResources().getConfiguration().orientation;
            if (orientation == Configuration.ORIENTATION_PORTRAIT) {
              if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270) {
                return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
              } else {
                return ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
              }
            }
            if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
              if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) {
                return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
              } else {
                return ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
              }
            }
            return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
          }
    

    【讨论】:

    • 由于此方法依赖于设备的自然方向,因此无法在每个设备上都按预期工作。
    【解决方案4】:

    getResources().getConfiguration().orientation 是了解当前使用方向的标准方法。但是,如果它不能满足您的需求,那么也许您可以使用传感器根据角度来计算它。阅读thisthis

    【讨论】:

    • 是的,我知道这一点。我只是想知道是否有一种方法可以返回有关屏幕方向的完整信息,包括它转向的一侧(不仅仅是横向或纵向),即倒置,左侧或右侧。
    • 是的,我明白你的意思。所以你可以做的是通过使用这些传感器来制作你自己的单一静态方法......
    【解决方案5】:

    我认为您的问题是您可以检测横向和纵向,但不能检测反向横向和反向纵向,因为旧版本不支持它们。要检测您可以做什么,您可以同时使用定向和旋转。我给你一个想法,它可能对你有用。

    试试这个,我想它可以解决你的问题。

                int orientation = getResources().getConfiguration().orientation;
                int rotation = getWindowManager().getDefaultDisplay().getRotation();
                int actual_orientation = -1;
                if (orientation == Configuration.ORIENTATION_LANDSCAPE
                &&  (rotation == Surface.ROTATION_0 
                ||  rotation == Surface.ROTATION_90)){
                    orientation = Configuration.ORIENTATION_LANDSCAPE;
                } else if (orientation == Configuration.ORIENTATION_PORTRAIT
                      &&  (rotation == Surface.ROTATION_0 
                       ||  rotation == Surface.ROTATION_90)) {
                    orientation = Configuration.ORIENTATION_PORTRAIT;
                } else if (orientation == Configuration.ORIENTATION_LANDSCAPE
                      &&  (rotation == Surface.ROTATION_180 
                       ||  rotation == Surface.ROTATION_270)){
                    orientation = //any constant for reverse landscape orientation;
                } else {
                    if (orientation == Configuration.ORIENTATION_PORTRAIT
                            &&  (rotation == Surface.ROTATION_180 
                             ||  rotation == Surface.ROTATION_270)){
                          orientation = //any constant for reverse portrait orientation;
                    }
                }
    

    【讨论】:

    • 是的,我最终做了一个类似的解决方案。我将其发布为答案。
    【解决方案6】:

    我最终使用了上面 Zoltán 的答案,效果很好,除非我在平板电脑(三星 P6210 Galaxy Tab 7.0 Plus)上尝试过。在纵向模式下,它返回 SCREEN_ORIENTATION_REVERSE_PORTRAIT。因此,在 else 语句中(如果自然方向是横向),我将案例交换为 ROTATION_90 和 ROTATION_270,一切似乎都正常。 (我没有足够的声誉将其发布为对 Zoltán 答案的评论。)

    【讨论】:

    • 你知道这是否也发生在其他横向平板电脑上吗?也许这两种情况应该换成所有自然景观设备?
    • 已确认,它也发生在 Asus Transformer prime 上,更换外壳修复它。
    【解决方案7】:

    您可以通过一种非常简单的方式做到这一点: 获取屏幕widhtheight。 当设备处于横向时,屏幕宽度总是会更高。

    Display display = getWindowManager().getDefaultDisplay();
        int width = display.getWidth(); 
        int height = display.getHeight();
        Toast.makeText(getApplicationContext(), "" + width + "," + height,
                Toast.LENGTH_SHORT).show();
        if (width > height) {
            Toast.makeText(getApplicationContext(), "LandScape",
                    Toast.LENGTH_SHORT).show();
        }
    

    【讨论】:

    • 问题实际上是如何获得详细的方向,即包括设备转动的方向。您建议的方法不会区分相反的方向,例如人像、倒立人像等
    【解决方案8】:

    这能解决您的问题吗?

    public static int getscrOrientation(Activity act)
    {
        Display getOrient = act.getWindowManager()
                .getDefaultDisplay();
    
        int orientation = getOrient.getOrientation();
    
        // Sometimes you may get undefined orientation Value is 0
        // simple logic solves the problem compare the screen
        // X,Y Co-ordinates and determine the Orientation in such cases
        if (orientation == Configuration.ORIENTATION_UNDEFINED) {
    
            Configuration config = act.getResources().getConfiguration();
            orientation = config.orientation;
    
            if (orientation == Configuration.ORIENTATION_UNDEFINED) {
                // if height and widht of screen are equal then
                // it is square orientation
                if (getOrient.getWidth() == getOrient.getHeight()) {
                    orientation = Configuration.ORIENTATION_SQUARE;
                } else { // if widht is less than height than it is portrait
                    if (getOrient.getWidth() < getOrient.getHeight()) {
                        orientation = Configuration.ORIENTATION_PORTRAIT;
                    } else { // if it is not any of the above it will defineitly
                                // be landscape
                        orientation = Configuration.ORIENTATION_LANDSCAPE;
                    }
                }
            }
        }
        return orientation; // return value 1 is portrait and 2 is Landscape
                            // Mode
    }
    

    【讨论】:

    • 就像我在问题中所说的那样。我需要知道屏幕的转动方向。纵向或横向信息不足。例如。如果它是一个高或纵向设备,如果它是横向的,我需要知道它是打开它的左侧还是右侧,等等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-16
    • 1970-01-01
    相关资源
    最近更新 更多