【问题标题】:Detect orientation change, when only portrait is allowed on Android检测方向变化,当 Android 上只允许纵向时
【发布时间】:2015-06-29 14:27:05
【问题描述】:

我必须解决以下问题:我有一个 Activity,它是 android:screenOrientation="portrait"。即使,当设备旋转到横向而 Activity 可见时,我必须启动另一个,并且,当设备旋转回纵向时,我必须 finish() 横向活动。我尝试使用BroadcastReceiver 执行此操作,但由于android:screenOrientation="portrait",此特殊活动没有收到任何广播。非常感谢任何帮助。

谢谢。

【问题讨论】:

标签: android android-orientation


【解决方案1】:

Philipp 在Get phone orientation but fix screen orientation to portrait 中的解决方案非常适合我:

您可以使用 SensorManager 类获取 Android 设备的方向,即使在 Manifest 中通过 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);

【讨论】:

  • 这会消耗太多电池。因此,SensorEventListener 不应用于这种情况。
【解决方案2】:

当在清单文件中设置了 android:screenOrientation="portrait" 或 "landscape" 时,如果您想这样做,仍然不会触发任何侦听器,请尝试以编程方式在您的 onConfigurationChanged() 中处理仅纵向模式,在这里您也将能够再次开始活动。

【讨论】:

  • 同意。如果您只需要一个方向,Android 不会通知您。但侦听器可能会起作用(从未尝试过)。
  • 答案是错误的,OrientationEventListener 在这种情况下工作正常
【解决方案3】:

您始终可以使用传感器找出您的方向;

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

【讨论】:

  • 您在发送之前尝试过这段代码吗?另外,我宁愿看一些文档...
  • 方位角、俯仰角和滚动角没有类型,就像 orient 一样,另外,你没有注册任何东西的监听器,你没有启用它,等等。更不用说 SensorEventListener 必须实现另一个方法才能从此接口创建对象。对不起,但我需要根据一些官方文档的正确答案。
【解决方案4】:

经过一番挣扎,我发现最好的方法是像这样使用 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()

【讨论】:

    【解决方案5】:

    你用过方向监听器吗?我不确定这是否正是您所需要的,但我收集到您想知道方向何时来回变化:

    http://developer.android.com/reference/android/view/OrientationListener.html

    【讨论】:

    • 你试过了吗?当你尝试这个方法时,你会看到方向监听器的回调被调用了很多次,即使是最轻微的移动。这不是我的选择。
    • 我的意思是这可能会有所帮助,但我需要编写一个算法来处理来自回调的数据,我真的没有时间。
    • 为什么'onOrientationChanged(int方向)'不适合你?以 90 度或 270 度的角度,它只会检测到侧翻时的变化。这不是你要找的吗? developer.android.com/reference/android/view/…
    • 顺便说一句,OrientationListener 已弃用。
    • 它仍然有效,对吧?或 OrientationEventListener?他们对你有用吗?
    【解决方案6】:

    您需要使用的类是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(); 或调用您喜欢的任何功能。

    祝你好运!

    【讨论】:

    • 我有一个活动,其中我有一个视图鳍状肢。当且仅当视图翻转器的特定子项位于顶部时,我才希望允许设备显示横向视图。这意味着如果用户在特定视图上,我只想捕捉风景事件。我不希望在轮换时重新创建其他视图(以及整个活动)。
    • 逻辑应该完全一样,只创建特定子视图的layout-land/和layout-port/版本。如果您可以使用 OrientationEventListener 来捕获事件,您也可以以这种方式手动重新膨胀子视图。
    • 尝试在设备上使用 OrientationEventListener,尝试旋转它,然后查看结果。然后试着解释一下,谢谢。
    【解决方案7】:

    您可以通过两种方式做到这一点,一种是收听其他帖子中讨论的广播消息,另一种选择如下。

    在清单中为活动设置android:configChanges="orientation",这将使您能够控制方向更改。通过这样做,您可以覆盖 onConfigurationChanged() 方法并开始您的新活动活动。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-26
      相关资源
      最近更新 更多