Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - 'sensorPortrait' orientation not working

Tags:

android

I have come across a problem where the orientation sensorPortrait does not work, i have tried enabling both through the manifest and within the activity itself with

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);

But this seems to just be locked in normal portrait mode, however if i try `fullSensor'

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);

which according to the docs

The orientation is determined by the device orientation sensor for any of the 4 orientations. This is similar to "sensor" except this allows any of the 4 possible screen orientations, regardless of what the device will normally do (for example, some devices won't normally use reverse portrait or reverse landscape, but this enables those). Added in API level 9.

and it does exactly that, all 4 orientations are possible. If i also try

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);

I am able to achieve reverse portrait, which leads me back to my original question, why does sensorPortrait not work? It looks like it has something to do with this line from the docs for `fullSensor'

regardless of what the device will normally do (for example, some devices won't normally use reverse portrait or reverse landscape, but this enables those)

So how do i enable it, is that possible and why does fullSensor seem to override it but not sensorPortrait? I can't seem to find any mention of how to do so. This question suggests that the PhoneWindowManager is responsible for this.

Is the ideal solution just to create an OrientationEventListener() and manually call setRequestedOrientation() manually depending on the values returned via onOrientationChanged(int orientation)?

like image 450
Joe Maher Avatar asked Dec 15 '16 23:12

Joe Maher


1 Answers

As a work around i have created a SensorPortraitActivity:

public class SensorPortraitActivity extends AppCompatActivity {

    private static final int PORTRAIT = 0;
    private static final int REVERSE_PORTRAIT = 180;
    private static final int OFFSET = 45;
    private static final int UNKNOWN = -1;

//  account for 0 = 360 (eg. -1 = 359)
    private static final int PORTRAIT_START = PORTRAIT - OFFSET + 360; 
    private static final int PORTRAIT_END = PORTRAIT + OFFSET;
    private static final int REVERSE_PORTRAIT_START = REVERSE_PORTRAIT - OFFSET;
    private static final int REVERSE_PORTRAIT_END = REVERSE_PORTRAIT + OFFSET;

    private OrientationChangeListener mListener;
    private OrientationEventListener mOrientationListener;
    private CurrentOrientation mCurrentOrientation;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mOrientationListener = new OrientationEventListener(this) {
            @Override
            public void onOrientationChanged(int i) {
                orientationChanged(i);
            }
        };
    }

    @Override
    protected void onResume() {
        super.onResume();
        mOrientationListener.enable();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mOrientationListener.disable();
    }

    //optional 
    public void setOrientationChangeListener(OrientationChangeListener listener){
        mListener = listener;
    }

    private void orientationChanged(int degrees) {

        if (degrees != UNKNOWN){

            if (degrees >= PORTRAIT_START || degrees <= PORTRAIT_END){

                if (mCurrentOrientation != CurrentOrientation.PORTRAIT){

                    mCurrentOrientation = CurrentOrientation.PORTRAIT;
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

                if (mListener != null){
                    mListener.onPortrait();
                }
            }
        } else if (degrees >= REVERSE_PORTRAIT_START && degrees <= REVERSE_PORTRAIT_END){

            if (mCurrentOrientation != CurrentOrientation.REVERSE_PORTRAIT){

                mCurrentOrientation = CurrentOrientation.REVERSE_PORTRAIT;
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);

                    if (mListener != null) {
                        mListener.onReversePortrait();
                    }
                }
            }
        }
    }

    interface OrientationChangeListener {
        void onPortrait();
        void onReversePortrait();
    }

    enum CurrentOrientation {
        PORTRAIT, REVERSE_PORTRAIT
    }
}

Although it does seem like overkill for something as simple as this.

To use it simple extend SensorPortraitActivity

public class ExampleActivity extends SensorPortraitActivity implements SensorPortraitView.OrientationChangeListener {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //set listener if you want callbacks
        super.setOrientationChangeListener(this);
    }

    @Override
    public void onPortrait() {
        //portrait orientation
    }

    @Override
    public void onReversePortrait() {
        //reverse portrait orientation
    }
}
like image 119
Joe Maher Avatar answered Nov 19 '22 07:11

Joe Maher