Mark
Mark

Reputation: 1650

onConfigurationChanged doesn't avoid activity restart on orientation change

I would like, for a camera app, to avoid redrawing the activity on orientation change. So far I've been using android:screenOrientation="landscape"

Now I want the icons to rotate according to orientation change.

Well, it should be very straightforward: Firstly the code line above is deleted. Then you set in the manifest for the activity:

android:configChanges="orientation|screenSize|keyboardHidden"

Finally, you override onConfigurationChanged in the activity:

    @Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        //Do something
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        //Do something
    }
}

Now, AFAIK, it should fire onConfigurationChanged instead restarting the activity (assuming it will be handled in onConfigurationChanged)

In practice, when orientation is changed, onConfigurationChanged is fired, but in addition to the unwanted rotation. How to cancel it? What am I missing?

Device: Xiaomi Mi2s API: 4.1.1

Thanks, Mark.

Upvotes: 1

Views: 1927

Answers (3)

Mark
Mark

Reputation: 1650

Well, after the traditional methods failed - I decided to implement orientation change routine by myself.

For this, firstly, I've returned android:screenOrientation="landscape" to the manifest.

Then, I've implemented sensor listener call back with some math:

private SensorEventListener listener = new SensorEventListener() {
    public void onSensorChanged(SensorEvent e) {
        if (e.sensor.getType()==Sensor.TYPE_ACCELEROMETER) {
            float x = e.values[0];
            float y = e.values[1];

            //update _angle in rotate()

            if (Math.abs(y) / Math.abs(x) < 1.0)
            {
                if (x<0 && _angle != 270f)
                    rotate(270f);
                else if(x>=0 && _angle != 90f)
                    rotate(90f);
            }
            else
            {
                if (y<0 && _angle != 180f)
                    rotate(180f);
                else if (y>=0 && _angle != 0f)
                    rotate(0f);
            }
        }

    }
            @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
            // TODO Auto-generated method stub

        }
    };

Works like a charm.

Upvotes: 0

Amrendra
Amrendra

Reputation: 2077

Try this:

@Override
public void onConfigurationChanged(Configuration newConfig) {

  if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
    //Do something
  } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
    //Do something
  }
  super.onConfigurationChanged(newConfig);
}

if you don't want to recreate activity, use orientation sensor for detecting orientation.

Upvotes: 0

Martin Cazares
Martin Cazares

Reputation: 13705

You need to prevent the parent from handling the config as follows:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(null);
    //TODO: Do nothing when orientation has changed...
}

As you can see all you need to do is pass null to the super method of onConfigurationChanged, so it will actually prevent from going through all the changes you want to avoid.

Regards!

Upvotes: 1

Related Questions