How do I detect screen rotation - android

I have an activity that is showing a compass, and I need to know the orientation of the screen to properly rotate the needle. I need to distinguish between 90° and 270° degree rotation to properly handle this.
When I rotate the screen (on my Nexus S at least) the activity's onCreate gets called, e.g. when I rotate from portrait to landscape mode. When I rotate from one landscape mode to the other with the top edge raised, onCreate() gets called twice (once for portrait orientation and once for the target landscape mode).
However, when I rotate with the bottom edge up, the screen rotates 180° and onCreate is not getting called. Is there an event that gets fired in this case?

You are correct that at a 180 degree rotation you will not get restarted or get a configuration change, because the configuration has not actually changed. (It is still in landscape or portrait, and everything else is the same.)
However if you are showing a compass, that must mean you are updating it from sensor events. Thus you can just call Display.getRotation() each time you get a sensor update to get the current rotation of the screen. In fact that you need is rotation of interpreting sensor events (or actually how your drawing of them will be modified when it gets to the screen), not just the orientation.
I found a relevant blog post that is well worth reading.
Be sure to read the SDK documentation.
Also check out the discussion about using Display.getRotation() to correctly remap sensor coordinates.

The helper class OrientationEventListener makes it very easy to get call backs on rotation. I would suggest you give it a try.

Just take a look at the SensorManager Documentation, there you can get the best examples and explanations of how to use the accelerometer to get the most precise informations. Instead of making the things just by detecting the phone orientation, with that API you can get the exactly rotation, just like used by racing games like Asphalt and Need For Speed.

As Monchote said, in order to make your needle rotate as expected on the compass, it's better to lock your UI to portrait or landscape, and change your needle angle according to the device rotation angle, which can be gained easily from OrientationListener.
In this way, no matter the auto rotation feature is opened or not by user, you can always get rotation angle change notification. Here's a good example for your reference.

Have a look at the OnConfigurationChanged method to track down the orientation change and re-arrange your UI as needed.
See some sample code

Related

Making an app with an arrow always pointing to the earths ground

Which sensor is needed to make an app where an arrow on the display is always pointing to the ground?
My app is always in landscape. Ive tried to use the Orientation sensor but it only works if Im holding my smartphone in portrait mode. The more I move my device to landscape values become instable und doesnt point to the ground anymore.
To be more specific, in portrait mode I can use y-axis (roll) to find out the angle, but the more Im rotating my device to landscape mode it doesnt work anymore with the y-axis.
Maybe its the wrong sensor or its a question of some trigonometry functions?
Any ideas? Please help me.
Ive found the solution.
The problem described is also known as Gimbbal Lock.
See here and here.
For me the solution can be found here and is the trivial sentence:
Using the camera (Y axis along the camera's axis) for an augmented
reality application where the rotation angles are needed:
remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR);
This way I can do what I want to do because the Gimbbal Lock is lying in a position where it doesnt argue me.

Is there a device and interface orientation in Android (like in iOS)?

Is there a way to get the device orientation in Android even if the interface orientation remains the same? I turn the device 180 degrees, the UI is upside down. But I still want to be notified.
You should set up an OrientationEventListener in the Activity you want to be notified of changes in.
Then you will have to specify the desired ScreenOrientation in the manifest for that Activity to prevent the screen from rotating.

SystemBar/BottomBar in Android

Sorry for my bad english.
I develop a game in which will be implemented autoOrientation, but when i rotate device and stage orientation is changed, then reinitialization process take too long time (because i use GPU to render game content), therefore i decided to disable autoOrientation and manually calculate the orientation of the device from accelerometer data, and then rotate the main game sprite accordingly to calculated orientation...and it works, but SystemBar remains static in its first position when game was launched. The question is how to set SystemBar position in Android, something like this
SetBarPosition(TOP / BOTTOM / RIGHT / LEFT);
In this case you should handle the orientation change yourself instead of disabling it. On android you should implement onConfigurationChanged() method and add to manifest that you handle orientation changes.

Listen for orientation change when screenOrientation="sensorLandscape"

I am wanting to listen for an orientation change in an activity. I've attempted some of the usual things,
onConfigurationChange with orientation in the android:configChanges element
in the manifest,
There's no restart of the activity, (proved with breakpoints), so I can't check getWindowManager().getDefaultDisplay().getRotation() after a rotation unless I check it constantly in my draw thread, which is wasteful.
I could use OrientationEventListener but this gets called for every degree change of the phone, which (imo) is also wasteful.
I am trying to detect the difference from LandscapeLeft and LandscapeRight. I'm unsure how else to approach it at this point.
I don't believe the OrientationEventListener will necessarily tell you whether or not the screen's orientation has changed since it only returns the degrees.
Using getWindowManager().getDefaultDisplay().getRotation() is probably the way to go, but you would have to know the device's default orientation since this will only tell you the rotation based on the default.
There's a decent blog about using the various sensors with orientation changes and the coordinate system here.

Is there a way to do a "setRotation()" either with a method or code?

So I want my app to always lock onto the natural orientation of the device. So basically, I want to force the rotation to 0 degrees. There's a getRotation() method here:
http://developer.android.com/reference/android/view/Display.html
However, there is no setRotation(int rotation) that would accept one of the Surface.ROTATION_X parameters found here:
http://developer.android.com/reference/android/view/Surface.html
So, is there some way to do this with a single line of code that will always work? Or would this have to be done with some code?
The only thing I can think of as a manual solution is the following, but I have some concerns about it.
I can use the display.getRotation(). Then I'll check if it's 0 or 180 degrees, after that I'll get the display height and width, and see which one is longer than the other. If it appears I'm in landscape mode, then I'll know that the device's natural orientation is landscape so I could set it to landscape. However if the rotation was 270 or 90, then I would know the natural orientation is portrait, and I could set it to portrait.
However, my concern is where to do this such that it always works. Let's say the user is rotating the screen as this piece of code is executing, if the device changes orientation in between the time I use the getRotation() method, and check the width against the height with some if statements and what not, I think it could throw everything off. What happens if I put this in onCreate() or onResume()? Is it possible that things can get out of wack?
Is it possible for a the onCreate() or onResume() to be interrupted by a screen re-orientation due to the user turn the device around? The other issue is that if you flip the device by 180 degrees, the activity is never destroyed, so I think the behavior of this situation could very whether it's a 90 degree turn, or a 180 degree turn.
You can "set" the screen orientation in the manifest. See here: http://developer.android.com/guide/topics/manifest/activity-element.html#screen
<activity
android:name=".Activity"
android:screenOrientation="portrait"
android:theme="#style/Theme.D1"
android:label="#string/title_activity"/>
The value you're probably looking for is; "user" The user's current preferred orientation. However, I would test this on several test cases to be sure. HTH!

Categories

Resources