A funny thing about writing code for Android is that you keep bumping into things that you can't get to work, and at first you don't understand why. After some thought, however, you realize that it all makes sense, and you can't even understand why you thought it would work in the first place.
One example of this is when I wanted an activity to have translucent background, just to make it look a bit cooler :) No problem, I just needed to change the theme of the activity to Theme.NoTitlebar.Translucent. Or so I thought.
At some point later when testing on a device, I suddenly found that the activity no longer flipped screen orientation. It stayed locked in portrait mode no matter what I did. It just didn't make sense! How could changing the background opacity screw up the orientation?
A general rule in Android, as far as I can tell, is:
All visible activities must be displayed in the same orientation. Either all are in portrait or all are in landscape mode. If one flips, then all others must flip too.
This rule makes perfect sense. I mean have you ever come across a window manager that would allow some windows in landscape mode and others in portrait? I haven't.
So what that this have to do with my problem? Well the thing was, I was launching my activity on top of the Launcher home screen. The home screen is locked in portrait mode, by setting the
screenOrientation in the manifest. Setting my activity to have a translucent background, meant that the home screen was still visible, hence also my activity got locked in portrait mode.
In fact, the home screen being visible alone was not enough to lock the orientation. It's also that my activity didn't specifically state any preference for the screen orientation preference. What's more, The behavior when orientation is unspecified is not defined by Android. The documentation says:
"unspecified" The default value. The system chooses the orientation. The policy it uses, and therefore the choices made in specific contexts, may differ from device to device.
So the problem I had may well be hardware specific. Remember that next time you get bug reports about non-rotating screens, this post may well give the answer.
A resolution of the problem would be to set the preferred screen orientation to
sensor, but as I discuss below, this is probably not a very good solution in most cases.
A funny thing about how this works is that it's the latest activity (the one highest up in the stack) that controls the orientation. It can force activities below it to whatever orientation it wants. This means that if you launch a completely transparent activity on top of another, you can override its orientation preference. It's not very useful, in fat one could even argue that it shouldn't be allowed to do this. In any case, it can be a fun trick to show off. Perhaps you are curious about how your favourite Android game would look in the 'other' orientation :)
The solution to set the
sensor in my activity was in fact not a very good solution. Why? Well it would force whatever activity was behind mine to also follow the sensor. When an activity changes orientation, the default action by the system is to destroy and recreate it. This will take a lot of time for some activities, in particular the home screen. So I would say that the
sensor preference is only useful if you are sure that the background activity can change orientation quickly.
My activity was the start activity, so I could not predict what its background could be. In the end, the only sensible solution in my case was to have an opaque background.