检测方向变化,仅允许在Android上使用纵向模式

5
我必须解决以下问题:我有一个Activity,它的android:screenOrientation="portrait"。即使设备在此Activity可见时被旋转到横向,我也必须启动另一个Activity,并且当设备旋转回纵向时,我必须在横向上完成Activity。我尝试使用BroadcastReceiver执行此操作,但由于android:screenOrientation="portrait",该特殊Activity不会接收任何广播。非常感谢您提供的任何帮助。
谢谢。

看一下这个:https://dev59.com/2H7aa4cB1Zd3GeqPvNAK#41104983 这个解决方案使用SensorManager。 - Maher Abuthraa
7个回答

8

Philipp在获取手机方向但锁定屏幕方向为纵向的解决方案对我非常有帮助:

您可以使用SensorManager类获取Android设备的方向,即使在清单文件中通过android:screenOrientation="portrait"禁用了自动方向切换。

请参考以下代码(由Philipp提供,参见上面的链接):

SensorManager sensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
    sensorManager.registerListener(new SensorEventListener() {
        int orientation=-1;;

        @Override
        public void onSensorChanged(SensorEvent event) {
            if (event.values[1]<6.5 && event.values[1]>-6.5) {
                if (orientation!=1) {
                    Log.d("Sensor", "Landscape");
                }
                orientation=1;
            } else {
                if (orientation!=0) {
                    Log.d("Sensor", "Portrait");
                }
                orientation=0;
            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
            // TODO Auto-generated method stub

        }
    }, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);

1
这将消耗太多的电池。由于这个原因,SensorEventListener 不应该用于这种情况。 - Mario Velasco

5

当在清单文件中设置android:screenOrientation="portrait"或"landscape"时,仍然不会触发任何监听器,但如果您想要这样做,请尝试在onConfigurationChanged()方法中以编程方式处理仅限于纵向模式,并且在此处您还将能够重新启动活动。


1
同意。如果您只想要一个方向,Android 不会通知您。但是监听器可能有效(从未尝试过)。 - shkschneider
2
答案是错误的,OrientationEventListener在这种情况下工作正常。 - insomnium_

1

经过一些探索,我发现最好的方法是使用 OrientationEventListener,如下所示:

private void addOrientationListener()
    {
        OrientationEventListener listener=new OrientationEventListener(getActivity(), SensorManager.SENSOR_DELAY_UI)
        {
            public void onOrientationChanged(int orientation) {

                if( (orientation>=230 && orientation<=290) || (orientation>=70 && orientation<=90))
                {
                    isLandscape=true;
                }
                else if(orientation==-1){
                    //KEEP THE CURRENT SATTE
                }
                else
                {
                    isLandscape=false;
                }
            }
        };
        if(listener.canDetectOrientation())
            listener.enable();
    }

在OnPause()中应调用disable()


1

您可以始终使用传感器来确定您的方向;

public static final int PORTRAIT        = 0;
public static final int PORTRAIT_REV    = 2;
public static final int LANDSCAPE       = 1;
public static final int LANDSCAPE_REV   = 3;

private final SensorEventListener mListener = new SensorEventListener() {

   public void onSensorChanged(SensorEvent event) {


            azimuth = event.values[0];
            pitch   = event.values[1];
            roll    = event.values[2];

            {
                if (pitch < -45 && pitch > -135) {
                    orient = PORTRAIT;
                } else if (pitch > 45 && pitch < 135) {
                    orient = PORTRAIT_REV;
                } else if (roll > 45) {
                    orient = LANDSCAPE;
                } else if (roll < -45) {
                    orient = LANDSCAPE_REV;
                }

            }

           // if(orient!=lastOrient && !orientChanging)
           // {
           //   orientChangeStart = System.currentTimeMillis();
           //   orientChanging = true;
           // }
}

你在发送代码之前试过这段代码吗?此外,我更愿意看到一些文档... - overbet13
方位角、俯仰角和翻滚角没有类型,就像方向、加法一样,您不需要将侦听器注册到任何东西上,也不需要启用它等等。更不用说SensorEventListener还有另一个方法,您必须实现才能从此接口创建对象。抱歉,但我需要根据一些官方文档得出正确的答案。 - overbet13

0
你需要使用的类是OrientationEventListener,假设你可以检测到屏幕旋转。如果你使用android:screenOrientation="portrait"强制屏幕进入特定方向,这些事件将不会触发。
相反,我建议创建两个layout.xml文件,并使用配置限定符来确定应该显示哪一个。(http://developer.android.com/guide/practices/screens_support.html
res/layout-land/my_layout.xml
res/layout-port/my_layout.xml

然后使用OrientationEventListener来检测屏幕旋转的情况。当屏幕从横向变为纵向时,您可以选择finish();或调用任何其他函数。

祝您好运!


我有一个活动,在其中我有一个视图翻转器。我想要允许设备在特定的子视图处于顶部时显示横向视图。这意味着我只想在用户处于特定视图时捕获横向事件。我不希望其他视图(和整个活动)在旋转时重新创建。 - overbet13
逻辑应该完全相同,只需创建特定子视图的layout-land/和layout-port/版本。如果您可以使用OrientationEventListener来捕获事件,也可以以这种方式手动重新填充子视图。 - SD_Guru
尝试在设备上使用OrientationEventListener,尝试旋转它并查看结果。然后尝试解释一下,谢谢。 - overbet13

0

你试过这个吗?当你尝试这种方法时,你会发现方向监听器的回调会在最微小的移动时被多次调用。对我来说,这不是一个选项。 - overbet13
我的意思是这可能有所帮助,但我需要编写一个算法来处理回调的数据,而我真的没有时间。 - overbet13
为什么' onOrientationChanged(int orientation)' 对你无效?使用90度或270度的参数,它只会在设备横向旋转时检测变化。这难道不是你要找的吗? http://developer.android.com/reference/android/view/OrientationEventListener.html#onOrientationChanged(int) - Wait what
顺便提一下,OrientationListener已经被弃用了。 - overbet13
它仍然可以工作,对吧?或者OrientationEventListener呢?它们对你有用吗? - Wait what

0

你可以用几种方法来实现,一种是像其他帖子中讨论的那样监听广播消息,另一种选择是如下所示。

在活动清单文件中为该活动设置android:configChanges="orientation",这将使您控制方向更改。通过这样做,您可以重写onConfigurationChanged()方法并启动新的活动。


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