2013-02-12 77 views
7

这可能很容易成为另一个问题的重复,我只是努力找出要搜索的内容。当锁定到一个方向时获取手机方向

我的相机应用程序被锁定为横向模式(清单)是这样的:

android:screenOrientation="landscape" 

不过,我想还是旋转的一些UI元素,当设备旋转为纵向(尽管机器人仍然会认为它的景观,但这是故意的)。

所以我已经试过这,检查方向

int rotation = this.getWindowManager().getDefaultDisplay() 
      .getRotation(); 
    int degrees = 0; 
    switch (rotation) { 
     case Surface.ROTATION_0: 
      Log.d("Rotation", "0"); 
      break; 
     case Surface.ROTATION_90: 
      Log.d("Rotation", "90"); 
      break; 
     case Surface.ROTATION_180: 
      Log.d("Rotation", "180"); 
      break; 
     case Surface.ROTATION_270: 
      Log.d("Rotation", "270"); 
      break; 
    } 

而且不幸的是,它总是返回90,无论我怎么打开手机。无论Android“认为”方向是什么,是否有更强大的方法来获取定位?

+0

当您检查方向是什么?在开展活动时? – 2013-02-12 15:37:18

+0

我希望能够不断检查它,以便我可以立即响应变化。所以我对每个相机帧进行检查(至少现在是这样) – Jameo 2013-02-12 15:49:14

+0

看看这个:http://stackoverflow.com/a/41104983/2267723这个解决方案使用SensorManager。 – 2016-12-12 16:15:18

回答

5

所以后,我想过这个问题,我意识到我可能只是实现了类似的算法什么的Android本身使用找出方向。我使用onSenseorChanged回调

public static final int UPSIDE_DOWN = 3; 
public static final int LANDSCAPE_RIGHT = 4; 
public static final int PORTRAIT = 1; 
public static final int LANDSCAPE_LEFT = 2; 
public int mOrientationDeg; //last rotation in degrees 
public int mOrientationRounded; //last orientation int from above 
private static final int _DATA_X = 0; 
private static final int _DATA_Y = 1; 
private static final int _DATA_Z = 2; 
private int ORIENTATION_UNKNOWN = -1; 
@Override 
public void onSensorChanged(SensorEvent event) 
{ 
    Log.d(TAG, "Sensor Changed"); 
    float[] values = event.values; 
    int orientation = ORIENTATION_UNKNOWN; 
    float X = -values[_DATA_X]; 
    float Y = -values[_DATA_Y]; 
    float Z = -values[_DATA_Z];   
    float magnitude = X*X + Y*Y; 
    // Don't trust the angle if the magnitude is small compared to the y value 
    if (magnitude * 4 >= Z*Z) { 
     float OneEightyOverPi = 57.29577957855f; 
     float angle = (float)Math.atan2(-Y, X) * OneEightyOverPi; 
     orientation = 90 - (int)Math.round(angle); 
     // normalize to 0 - 359 range 
     while (orientation >= 360) { 
      orientation -= 360; 
     } 
     while (orientation < 0) { 
      orientation += 360; 
     } 
    } 
    //^^ thanks to google for that code 
    //now we must figure out which orientation based on the degrees 
    Log.d("Oreination", ""+orientation); 
    if (orientation != mOrientationDeg) 
    { 
     mOrientationDeg = orientation; 
     //figure out actual orientation 
     if(orientation == -1){//basically flat 

     } 
     else if(orientation <= 45 || orientation > 315){//round to 0 
      tempOrientRounded = 1;//portrait 
     } 
     else if(orientation > 45 && orientation <= 135){//round to 90 
      tempOrientRounded = 2; //lsleft 
     } 
     else if(orientation > 135 && orientation <= 225){//round to 180 
      tempOrientRounded = 3; //upside down 
     } 
     else if(orientation > 225 && orientation <= 315){//round to 270 
      tempOrientRounded = 4;//lsright 
     } 

    } 

    if(mOrientationRounded != tempOrientRounded){ 
      //Orientation changed, handle the change here 
     mOrientationRounded = tempOrientRounded; 

    } 
} 

它看起来更complecated比它,但只知道它的工作原理(我会说同样还有一个工作系统)。不要忘记登记的onResume和您的onPause更换传感器事件侦听器加速

+0

只在活动中有用。在很多情况下,您需要确定活动外的方向。 – AndroidDev 2013-07-26 16:03:10

+0

例如???另外,在这个问题中,我承认我正在做的事情并不正常,但是我正在使用 – Jameo 2013-07-26 16:19:35

+0

服务来处理图像处理。 – AndroidDev 2013-07-26 20:05:36

3

为了检测我用这个寄存器的方向来的SensorManager:

mSensorOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);  
mSensorManager.registerListener(this, mSensorOrientation, SensorManager.SENSOR_DELAY_NORMAL); 

然后将此用于检测取向的变化,在评论中,你可以把你自己的方法实现。

常量:

public static final int LYING = 0; 
public static final int LANDSCAPE_RIGHT = 1; 
public static final int PORTRAIT = 2; 
public static final int LANDSCAPE_LEFT = 3; 



public void onSensorChanged(SensorEvent event) { 

Sensor sensorEvent = event.sensor; 

if ((sensorEvent.getType() == Sensor.TYPE_ORIENTATION)) { 

    float [] eventValues = event.values; 

    // current orientation of the phone 
    float xAxis = eventValues[1]; 
    float yAxis = eventValues[2]; 

    if ((yAxis <= 25) && (yAxis >= -25) && (xAxis >= -160)) { 

     if (previousOrientation != PORTRAIT){ 
      previousOrientation = PORTRAIT; 

      // CHANGED TO PORTRAIT 
     } 

    } else if ((yAxis < -25) && (xAxis >= -20)) { 

     if (previousOrientation != LANDSCAPE_RIGHT){ 
      previousOrientation = LANDSCAPE_RIGHT; 

      // CHANGED TO LANDSCAPE RIGHT 
     } 

    } else if ((yAxis > 25) && (xAxis >= -20)){ 

     if (previousOrientation != LANDSCAPE_LEFT){ 
      previousOrientation = LANDSCAPE_LEFT; 

      // CHANGED TO LANDSCAPE LEFT 
     } 
    } 
} 

}

+0

Sensor.TYPE_ORIENTATION在API 8中已被弃用。我现在正在测试它,但我可能不得不寻找更向前兼容的东西。它宣称SensorManager.getOrientation是您应该使用的代替 – Jameo 2013-02-12 16:16:04

+0

我想出了一个不同的方式来做到这一点,您可能想看看,如果你仍然在使用你的方法。它不适用于我的Android 4.2手机 – Jameo 2013-02-13 14:20:06

+0

不错,发布回复并接受你自己;) – PaNaVTEC 2013-02-13 14:26:33

1

做一些研究和尝试一些东西后,它只是为我工作,当我设置的传感器:

mSensorOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 

Sensor.TYPE_ORIENTATION根据来自不同人的一些示例代码来取回取向,已经被弃用并给我带来不好的结果。我真的不知道它是否可以,但它对我有用。

0

@panavtec答案的翻译API 23,使用this作为参考

class MyActivity extends Activity implements SensorEventListener { 

    private SensorManager sensorManager; 
    private float[] lastMagFields = new float[3];; 
    private float[] lastAccels = new float[3];; 
    private float[] rotationMatrix = new float[16]; 
    private float[] orientation = new float[4]; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); 
    } 

    protected void onResume() { 
     super.onResume(); 
     sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_GAME); 
     sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); 
    } 

    protected void onPause() { 
     super.onPause(); 
     sensorManager.unregisterListener(this); 
    } 

    public void onAccuracyChanged(Sensor sensor, int accuracy) { 
    } 

    public void onSensorChanged(SensorEvent event) { 
     switch (event.sensor.getType()) { 
      case Sensor.TYPE_ACCELEROMETER: 
       System.arraycopy(event.values, 0, lastAccels, 0, 3); 
       break; 
      case Sensor.TYPE_MAGNETIC_FIELD: 
       System.arraycopy(event.values, 0, lastMagFields, 0, 3); 
       break; 
      default: 
       return; 
     } 

     if (SensorManager.getRotationMatrix(rotationMatrix, null, lastAccels, lastMagFields)) { 
      SensorManager.getOrientation(rotationMatrix, orientation); 

      float xAxis = (float) Math.toDegrees(orientation[1]); 
      float yAxis = (float) Math.toDegrees(orientation[2]); 

      int orientation = Configuration.ORIENTATION_UNDEFINED; 
      if ((yAxis <= 25) && (yAxis >= -25) && (xAxis >= -160)) { 
       Log.d(TAG, "Portrait"); 
       orientation = Configuration.ORIENTATION_PORTRAIT; 
      } else if ((yAxis < -25) && (xAxis >= -20)) { 
       Log.d(TAG, "Landscape Right"); 
       orientation = Configuration.ORIENTATION_LANDSCAPE; 
      } else if ((yAxis > 25) && (xAxis >= -20)){ 
       orientation = Configuration.ORIENTATION_LANDSCAPE; 
       Log.d(TAG, "Landscape Left"); 
      } 
     } 
    } 
}