Get phone orientation when locked in one orientation

It may just be a duplicate of another question, I'm just trying to figure out what to look for.

My camera application is blocked in landscape mode (in the manifest) as follows:

android:screenOrientation="landscape" 

However, I still want to rotate some user interface elements when the device rotates into a portrait (although the android will still think about it in the landscape, but it’s on purpose).

So I tried this to check the orientation

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

And, unfortunately, it always returns 90, regardless of how I rotate the phone. Is there a more reliable way to get orientation, no matter what Android thinks about orientation?

+7
source share
4 answers

So, after I thought about this, I realized that I could just implement a similar algorithm, like what Android itself uses to determine the orientation. I do this using the onSenseorChanged callback

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

It looks more complete than it is, but just know that it works (I would say as good as the system works). Remember to register your sensor change event listener in onResume and onPause for the accelerometer

+5
source

To determine the orientation, I use this to register with the sensormanager:

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

And then this is to determine the orientation of changes, in the comments you can put your own implementation of the methods.

Constants:

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

}

+3
source

After doing some research and trying some things, it only works for me when I install Sensor as:

 mSensorOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 

Sensor.TYPE_ORIENTATION is deprecated and gave me poor results according to some code examples from different people to get the orientation. I don't know if this is good or not, but it worked for me.

+1
source

Translating @panavtec response to API 23 using this as a reference

 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"); } } } } 
0
source

All Articles