OnConfigurationChanged is not called as soon as setRequestedConfiguration is used

I set am activity to handle configuration changes, and this works, which means that onConfigurationChanged() is called when the orientation changes.

In activity there is a button for explicit orientation change. When clicked, it is called setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) .

Then the orientation will be irrevocably set and onConfigurationChanged() no longer called.

How to change the orientation when the user clicks the button without losing the onConfigurationChanged() callback?

+6
source share
3 answers

This is how I solved it. I know that he invents the wheel, but he meets my requirements, and I did not find a suitable way to deal with standard sdk tools.

First create an OrientationManager class that listens for orientation changes

 public class OrientationManager extends OrientationEventListener{ private static final String TAG = OrientationManager.class.getName(); private int previousAngle; private int previousOrientation; private Context context; private OrientationChangeListener orientationChangeListener; private static OrientationManager instance; private OrientationManager(Context context) { super(context); this.context = context; } public static OrientationManager getInstance(Context context){ if (instance == null){ instance = new OrientationManager(context); } return instance; } public int getOrientation(){ return previousOrientation; } public void setOrientation(int orientation){ this.previousOrientation = orientation; } @Override public void onOrientationChanged(int orientation) { if (orientation == -1) return; if(previousOrientation == 0){ previousOrientation = context.getResources().getConfiguration().orientation; if (orientationChangeListener != null){ orientationChangeListener.onOrientationChanged(previousOrientation); } } if (previousOrientation == Configuration.ORIENTATION_LANDSCAPE && ((previousAngle > 10 && orientation <= 10) || (previousAngle < 350 && previousAngle > 270 && orientation >= 350)) ){ if (orientationChangeListener != null){ orientationChangeListener.onOrientationChanged(Configuration.ORIENTATION_PORTRAIT); } previousOrientation = Configuration.ORIENTATION_PORTRAIT; } if (previousOrientation == Configuration.ORIENTATION_PORTRAIT && ((previousAngle <90 && orientation >= 90 && orientation <270) || (previousAngle > 280 && orientation <= 280 && orientation > 180)) ){ if (orientationChangeListener != null){ orientationChangeListener.onOrientationChanged(Configuration.ORIENTATION_LANDSCAPE); } previousOrientation = Configuration.ORIENTATION_LANDSCAPE; } previousAngle = orientation; } public void setOrientationChangedListener(OrientationChangeListener l){ this.orientationChangeListener = l; } public interface OrientationChangeListener{ public void onOrientationChanged(int newOrientation); } } 

Then, in your implementation, we implement the OrientationChangeListener and override onOrientationChanged() :

 public class MyActivity extends Activity implements OrientationChangeListener{ private OrientationManager orientationManager; @Override public void onCreate(Bundle b){ orientationManager = OrientationManager.getInstance(this); orientationManager.setOrientationChangedListener(this); } @Override public void onOrientationChanged(int newOrientation) { orientation = newOrientation; if (newOrientation == Configuration.ORIENTATION_LANDSCAPE){ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); setLandscapeConfig(); }else{ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); setPortraitConfig(); } } 

Therefore, I no longer use onConfigurationChanged , but I save the following line in the manifest: android: configChanges = "orientation | Screen size"

+5
source

Call setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); activates onConfigurationChanged . You can set the timer as follows:

 // Force orientation to portrait setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT); // Reactivate sensor orientation after delay Timer mRestoreOrientation = new Timer(); mRestoreOrientation.schedule(new TimerTask() { @Override public void run() { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); } }, 2000); 

We can only assume that the user will independently switch the device to a forced orientation within the delay, which can lead to poor user experience.

+2
source
 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) 

This will cause the onConfigurationChanged function to stop working. If you want it to work, try adding this to your manifest as part of this action:

 android:configChanges="orientation|screenSize" 

The screenSize attribute is for API 13+ only, so if it's lower you don't need it

+1
source

All Articles