QML: Change Android screen orientation programmatically


In case your Android app require to dynamically set screen orientation for some particular interface is possible to directly call the system API allowing to choose one of the two standard orientations LANDSCAPE or PORTRAIT.



Full project source can be found here

Basically the solution is very easy. By using JNI interface is possible to call from QML (or C++ layer) the Android native API setRequestedOrientation() for set your desired orientation. Since this API can be called by main activity there is no need to add a custom java layer but can be called directly from C++ code as follow:

bool AndroidInterface::setScreenOrientation(int orientation)
{
    QAndroidJniObject activity = QtAndroid::androidActivity();

    if(activity.isValid())
    {
        activity.callMethod<void>("setRequestedOrientation", "(I)V", orientation);
        return true;
    }
 
    return false;
}

The constant value to use as param can be found in the Android official documentation here. Code on QML side is very simple too as follow:

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Android Screen Orientation Example")
    color: "darkCyan"

    readonly property int android_SCREEN_ORIENTATION_LANDSCAPE: 0
    readonly property int android_SCREEN_ORIENTATION_PORTRAIT: 1

    Column {
        width: 300
        anchors.centerIn: parent
        spacing: 30

        Button {
            width: parent.width
            text: "SCREEN_ORIENTATION_LANDSCAPE"
            onClicked: android.setScreenOrientation(android_SCREEN_ORIENTATION_LANDSCAPE)
        }
        Button {
            width: parent.width
            text: "SCREEN_ORIENTATION_PORTRAIT"
            onClicked: android.setScreenOrientation(android_SCREEN_ORIENTATION_PORTRAIT)
        }
    }
}

Basically this is all you need to set orientation as you require, however, just for your knowledge, there are a couple of info you may be interested to know. In case you use Qt Creator for generate the AndroidManifest.xml required permission are already set but for "manually" generated file the required params inside xml for allow this call to work correctly are the following:

android:configChanges="orientation|screenSize|..."

In add of this we use in this example the params SCREEN_ORIENTATION_LANDSCAPE and SCREEN_ORIENTATION_PORTRAIT just for compatibility reasons since these value work from the first version of Android. However, from Android version 9 and above, new params has been added: 

SCREEN_ORIENTATION_SENSOR_PORTRAIT
SCREEN_ORIENTATION_SENSOR_LANDSCAPE

This new params different from the first one for use use of the device sensor for rotate based to the orientation of the device. Params used in the example set the orientation in a fixed mode, that's mean if the user rotate the device of 180 degree the screen orientation remain unchanged. On the contrary using the new params the screen will rotate on the opposite side always keeping the orientation requested.


Comments

Popular posts from this blog

Access GPIO from Linux user space

Android: adb push and read-only file system error

Tree in SQL database: The Nested Set Model