Nick
Nick

Reputation: 3461

Android: stack of disabled orientation changes

My application is designed to be "landscape-only". Rotation between left and right landscape must be supported so I am using android:screenOrientation="sensorLandscape".

However, there's a mini-game in my app when rotation must be disabled completely (because this mini-game is to be controlled by device tlting). After mini-game has finished, orientation handling policy must be restored back to sensorLandscape.

The standard method to disable orientation change is to call

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);

But not in the case! As mentioned here (and checked by me), it leads to orienation change to default state (that may be portrait).

Hence, the only way to go from sensorLandscape to "disableRotation" is to set explicitly desired orientation. So I have a choice: either call

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

or

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);

Obviously, I need to pass a current orientation, but it seems that Android has no function to get it!

getResources().getConfiguration().orientation returns either Configuration.ORIENTATION_PORTRAIT or Configuration.ORIENTATION_LANDSCAPE that is of no use.

getWindowManager().getDefaultDisplay().getRotation() seems to be more promising. It returns Surface.ROTATION_0 ... Surface.ROTATION_270 and I tried to use a logic as follows:

int getCurrentOrintation()
{
    final int rot = getWindowManager().getDefaultDisplay().getRotation();
    if (Surface.ROTATION_0 == rot || Surface.ROTATION_90 == rot)
    {
        return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
    }
    return ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
}

It works fine on Google Nexus, but returns flipped oreintation on Kindle Fire HD.

So, is it possible in principle to temporarily lock orientation change in Android?

Upvotes: 3

Views: 278

Answers (3)

Karan_Rana
Karan_Rana

Reputation: 2823

You could use the following code to get the current orientation and lock it.

        int currentOrient = getResources().getConfiguration().orientation;
        if (currentOrient == Configuration.ORIENTATION_LANDSCAPE) 
        {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);//Lock to Landscape mode
        }
        else
        {
           setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);//Lock to Potrait mode
        }

Upvotes: 0

Submersed
Submersed

Reputation: 8870

You can lock orientation for specific activities by declaring screenOrientation="locked" in your android manifest, or by using the programmatic equivalent - ActivityInfo.SCREEN_ORIENTATION_LOCKED. However, this was added in API level 18, so it's limited to new devices. See the manifest documentation for more info.

Upvotes: 1

FunkTheMonk
FunkTheMonk

Reputation: 10938

Forcing the orientation does not disable the accelerometer / gyroscope sensors, so you shouldn't need to remove the orientation lock.

You should however note that the values given by the sensors are in a standard sensor coordinate system:

Accelerometers use the standard sensor coordinate system. In practice, this means that the following conditions apply when a device is laying flat on a table in its natural orientation:

If you push the device on the left side (so it moves to the right), the x acceleration value is positive. If you push the device on the bottom (so it moves away from you), the y acceleration value is positive.

If you push the device toward the sky with an acceleration of A m/s2, the z acceleration value is equal to A + 9.81, which corresponds to the acceleration of the device (+A m/s2) minus the force of gravity (-9.81 m/s2).

The stationary device will have an acceleration value of +9.81, which corresponds to the acceleration of the device (0 m/s2 minus the force of gravity, which is -9.81 m/s2).

Upvotes: 0

Related Questions