M. Sherbeeny M. Sherbeeny - 4 months ago 28
Android Question

Android: How to force reverse portrait orientation even if the device auto-rotate screen is off?

I'm working on an app/game that should switch between portrait and reverse portrait in multiplayer mode. (Mainly because each player might use the keyboard on his/her turn while the device is fixed on the table between them.)

My app works fine when the auto-rotate is ON.. But the reverse portrait orientation is NEVER achievable when the device auto-rotate is OFF!

What I did so far is that I've set the orientation in the manifest file:

<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>


then I change the orientation programmatically in runtime by calling this method when needed:

public void rotateScreen(boolean reverse){

if (reverse) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
}

else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}


But that still doesn't force to reverse portrait orientation if the device auto-rotation is OFF.

I also tried the onConfigurationChanged method, but it didn't work as well. I think it only gets called AFTER changing the orientation already, not before!

I even tried screenOrientation="reversePortrait" in the manifest file, but even that is ineffective when auto-rotation is OFF.

Answer

After lots of researching, seems that the only way to override the device locked orientation and set the screen to a reverse portrait orientation is to force-enabling the device auto-rotate.

first, must add this permission in the manifest file above the tag:

<uses-permission android:name="android.permission.WRITE_SETTINGS" />

then, define something like that in the mainActivity:

public boolean enableAutoRotate(){

        boolean isAutoRotate = android.provider.Settings.System
                .getInt(getContentResolver(),Settings.System.ACCELEROMETER_ROTATION, 1) == 1;

        if (!isAutoRotate){
            try {
                android.provider.Settings.System
                        .putInt(getContentResolver(),Settings.System.ACCELEROMETER_ROTATION, 1);

            } catch (Exception e){
                e.printStackTrace();
            }
        }

        isAutoRotate = android.provider.Settings.System
                .getInt(getContentResolver(),Settings.System.ACCELEROMETER_ROTATION, 1) == 1;

        return isAutoRotate;
}

The try and catch is important to prevent the app from crashing if the user didn't give or removed the permission.

then, set the orientation when needed using something like this:

public void rotateScreen(boolean reverse){

        if (enableAutoRotate()){
            if (reverse) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);

            }

            else {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

            }
        }
    }

rotateScreen method can also be boolean instead of void, if needed.