Problem with getCurrentOrientation() method on Android


#1

There’s a problem with the Android implementation of the getCurrentOrientation() method that’s in the juce_Android_Windowing.cpp file.

The implementation of the getCurrentOrientation() method uses the getRotation() method in the Android Display class and translates the rotation returned by the method directly into a screen orientation value.

But as the documentation of that method states, getRotation() returns the rotation of the screen from its “natural” orientation.

https://developer.android.com/reference/android/view/Display.html#getRotation()

So, to translate the rotation into the screeen orientation you would first need to know what a device’s “natural” orientation is, which the current implementation doesn’t do.

If you launch an Android project in the 10.1 WXGA tablet emulator built into Android Studio with the Landscape orientation, you’ll see that Juce’s method says the orientation is portrait when it’s landscape and vice versa.


#2

Thanks for reporting. I will have a look.


#3

Looking at the documentation of Juce’s own Desktop::getCurrentOrientation() method again it doesn’t actually say that the Desktop::upright and Desktop::upsideDown means the device is in portrait mode, and the other orientations mean it’s in landscape. You can translate the values that way on iOS, but perhaps, getCurrentOrientation() is behaving as the API defines it, although it’s less useful if it’s meaning is that ambiguous…

If it is behaving as intended, the question remains how you should determine on Android whether the device is in portrait or landscape… Android’s Configuration class has a field indicating whether it’s in Portrait or Landscape… One could just check the active screen dimensions…


#4

Yeah, Android has introduced some ambiguity around screen orientation. The key setting in emulator is the Startup orientation:

If Portrait is chosen (which seems to be the default), then all works as expected. If Landscape is chosen though, one can see the issue you described that portrait is reported when the device is in landscape. This does look unintuitive indeed, however, if one looks at emulator settings, the emulator also claims at this point that the device is in portrait mode, so we are in sync with what the emulator says:

Now th question is: does this issue affect any real hardware devices you know? I have tried on a few tablets and all worked fine. It seems to be only the issue if Landscape is chosen as the Startup orientation in the emulator, so perhaps this will never be the issue on a real device?


#5

This is a problem on the Samsung Galaxy Tab S 10.5. I started looking at this issue because someone doing some testing for us reported some screen layout problems on that tablet and looking at the screenshots he sent it was obvious that our app was using a portrait layout strategy in landscape orientation and vice versa.


#6

Ok, thanks.

The problem with Android’s Configuration is that it only says portrait or horizontal which is not enough for juce::Desktop::DisplayOrientation that has 4 values. Configuration is however correct about portrait vs horizontal state indeed.

I will have a look for a solution that reports 4 directions correctly at all times when there is a convenient moment.


#7

For the record, I’ve looked more into this and I am not aware of a reliable method that will return all 4 possible values of juce::Desktop::DisplayOrientation and that will work both for devices with natural portrait and landscape orientations.

If an app always allowed both portrait and landscape orientations, then this can be done by observing both android.content.res.Configuration.orientation and sensor orientation from accelerometer to figure out what is the natural device orientation. This is because the sensor always measures the angle from the natural device orientation (e.g. orientation == landscape and sensor orientation 90 degrees would mean that natural orientation is portrait). This scheme does not work however if the app e.g. allows only landscape orientation. For instance for the above example, if portrait orientation is disallowed by the app, there is no way to know what is the natural orientation of the device. Observing screen metrics also does not work, because Android always returns same width & height no matter what is the orientation.

If anyone comes with a reliable solution, give me a ping!