23

I need to act differently in onStart() method depending on how onCreate() was called in result of orientation change or not. Is that possible to check it?

Actually what I need is to do something when activity starts except a case when user changes orientation.

I need to clearly distinguish cases when user just switched to another application and returned back OR he changed device's orientation.

Eugene
  • 59,186
  • 91
  • 226
  • 333

8 Answers8

14

Following Nahtan's idea I wrote this:

in onCreate():

if ( (oldConfigInt & ActivityInfo.CONFIG_ORIENTATION)==ActivityInfo.CONFIG_ORIENTATION ) {
    // ... was rotated
} else {
    // ... was not rotated
}

in onDestroy():

super.onDestroy();
oldConfigInt = getChangingConfigurations();
tos
  • 996
  • 1
  • 10
  • 20
10
public class MyActivity extends Activity {
    boolean fromOrientation=false;
    SharedPreferences myPrefLogin;
    Editor prefsEditor;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        prefsEditor = myPrefLogin.edit();
        myPrefLogin = this.getSharedPreferences("myPrefs", Context.MODE_WORLD_READABLE);
        fromOrientation = myPrefLogin.getString("fromOrient", false);

        if(fromOrientation) {
             // do as per need--- logic of orientation changed.
        } else {
             // do as per need--- logic of default onCreate().
        }
    }

    @Override
    public Object onRetainNonConfigurationInstance() {
        prefsEditor.putString("fromOrient", true);
        prefsEditor.commit();
        return null;
    }

    @Override
    protected void onDestroy() {
        if(fromOrientation) {
            prefsEditor.putString("fromOrient", false);
            prefsEditor.commit();
        }
        super.onDestroy();
    }  
}

flag fromOrientation(tells the state either configuration had been change or not) above we had done like by defalut we are considering that onCreate() is not called from by changing orientation. If orientation changed(onRetainNonConfigurationInstance()) then we set the flag value in preference which let us know whether onCreate() is called from on orientation or not. And finally onDestroy() we again reset the orientation flag.

Bondax
  • 3,143
  • 28
  • 35
Mohammed Azharuddin Shaikh
  • 41,633
  • 14
  • 96
  • 115
  • 1
    This is not going to work anymore. See http://developer.android.com/guide/topics/resources/runtime-changes.html instead. – Kesty Feb 06 '16 at 22:12
5

Just check the bundle: when the activity is first started the bundle will be null. If there is an orientation change, it should be non-null.

From the android docs:

If the activity is being re-initialized after previously being shut down then this Bundle contains the data it most recently supplied in onSaveInstanceState(Bundle). Note: Otherwise it is null.

Edit: I don't think you have to supply a bundle in onSaveInstanceState for it to be non-null after an orientation change, but that would be trivial.

Nathan Fig
  • 14,970
  • 9
  • 43
  • 57
  • Actually what I need is to do `something` when activity starts except a case when user changes orientation (copied from description) – Eugene Sep 08 '11 at 19:31
  • Then just check if the bundle is null in onCreate, and if so, do the "something". – Nathan Fig Sep 09 '11 at 02:33
  • Gotcha; misunderstood that you just wanted to identify the first call. In that case I think I have a better answer I'll post seperately. – Nathan Fig Sep 09 '11 at 08:45
  • Works for me when I have a Timer in an activity that I want to start once, and the activity is finished before being started again. – Matthew Mitchell Oct 09 '13 at 15:03
5

Try getChangingConfigurations. Use this to discover when the activity is being destroyed because of an orientation change, set a flag, and check that flag when onCreate is called.

This has the advantage of letting you know why the activity is restarting without overriding orientation configuration in the manifest.

Nathan Fig
  • 14,970
  • 9
  • 43
  • 57
  • As per the reference document, this method is not 100% reliable though, and is recommended to be used only as a hint – Price Mar 07 '15 at 08:04
1

As others have said, save the state:

public class MyActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(savedInstanceState == null) {
            // app started afresh, don't check orientation
            /* do application first-run stuff */
        } else {
            // re-started, so check for orientation change
            boolean orientationChanged = false;
            if(savedInstanceState != null) {
                int lastOrientation = savedInstanceState.getInt("last_orientation");
                orientationChanged = (getOrientation() != lastOrientation);
            }

            if(orientationChanged) {
                // orientation changed
                /* do stuff */
            } else {
                // orientation has not changed
                /* do stuff */
            }
        }
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        savedInstanceState.putInt("last_orientation", getOrientation());
    }

    private int getOrientation() {
        // ...
    }
}
Dave
  • 6,064
  • 4
  • 31
  • 38
  • This would not work if you minimize the application being in portrait mode and start it again from landscape mode. In this case you would have different orientations and you trigger your if condition, which should not happen by requirement. – Eugene Sep 08 '11 at 19:30
  • Why do you need to determine if the user has changed orientation inside or outside of your Activity? – Dave Sep 09 '11 at 08:14
  • Because I need to one one thing when user launches the application, but not when he uses it (like change orientation of his device). – Eugene Sep 09 '11 at 09:58
  • The simplest way to check if the user has launched the game afresh is to check if `savedInstanceState` is null (as suggested by Nathan), which you can add to the above code. I think you're getting bogged down by the concept of apps being 'open' or 'closed' (ala a PC), when really, in Android, you shouldn't be differentiating between the two states. – Dave Sep 09 '11 at 10:37
  • Actually, Nathan's answer is definitely worth chasing up! – Dave Sep 09 '11 at 10:38
  • You should differentiate because if you work in portrait mode your currentOrientation == 1 (for example), then you switch to another app, change orientation to landscape and switch back to the app. Your currentOrienataion == 0. In this case you have oldOrientation != currentOrientation -> orientation changed and the `thing` I need to do when user start the app doesn't happen. I hope I'm clear this time. – Eugene Sep 09 '11 at 11:08
  • See amended code. Is that closer to what you want? If the app has been started up afresh, the orientation is not checked at all. Otherwise, it's checked to see if it's changed. – Dave Sep 09 '11 at 16:00
  • there would be a case when user worked with app, then switched to another, changed orientation then back to the app and it triggers the case orientations are different and code executed. This is one special case which make this hard to do because you never know was the application restarted because of user's switching to another app and then returning to it OR it was restarted because of orientation change. That's the problem. Sorry for making it so unclear all this time. – Eugene Sep 09 '11 at 18:27
0

You can try the following. On each onStart, you can save the current orientation (take a look here). If it is the first onStart call, do nothing, on other calls, check if the orientation has changed and do what you need.

private int m_currentOrientation = -1;

public void onStart()
{
   int oldOrientation = m_currentOrientation; // 
   m_currentOrientation = getCurrentOrientation(); // As in the link above
   if ((oldOrientation != -1) && (oldOrientation != m_currentOrientation))
   {
       // Do what you need
   }
}
Lior Ohana
  • 3,467
  • 4
  • 34
  • 49
  • This doesn't work because `m_currentOreintation` is always `-1` because on each orientation change new instance of your class activity instantiated. – Eugene Sep 04 '11 at 19:06
  • 1
    You can use the onSaveInstanceState, take a look here: http://stackoverflow.com/questions/151777/how-do-i-save-an-android-applications-state/151940#151940 – Lior Ohana Sep 04 '11 at 19:22
  • Anyway `onCreate()` can happen not only after orientation change, but in some other cases also (for instance, being in app go to home screen and back) – Eugene Sep 04 '11 at 19:45
  • But in that case, the m_CurrentOrientation will be the same. – Lior Ohana Sep 04 '11 at 19:56
  • @Lior Ohana, the value of the oldOrientation will always be the same, because when there is config changes the whole activity restarts itself, thus oldOrientation remains the same. – Nikola Despotoski Sep 07 '11 at 12:34
  • @Nikola, that's not completely true because you can save the value in saveInstanceState(). This approach just doesn't work when you just start the app second time, when there were no conf changes. – Eugene Sep 07 '11 at 12:37
  • @AndroidNoob, You wrote that it can happen "not only after orientation change", I know, but that's OK because the value of the m_currentOrientation will be the same when the change was not orientation. No? – Lior Ohana Sep 07 '11 at 14:13
  • @Lior, what you proposed is correct, but I've updated a description a little bit, the case became a little bit harder. Your suggestion doesn't work if you just start the application second time, the value would be -1 and two values are equal, this won't trigger the case, but it should. I need some other approach. – Eugene Sep 07 '11 at 14:48
0

In that case, why don't you handle configuration chanages (orientation) by yourself. Tell android not to handle screen orientation.

android:configChanges="keyboardHidden|orientation"

Then you just override onConfigurationChanged method to get your rearranging of view or whatsoever things need to be done. Leave things that you don't wanna get executed.

@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  //do your jobs 
}
PH7
  • 3,926
  • 3
  • 24
  • 29
  • 1
    This will cause problems down the road if he wishes to have different layouts for portrait and landscape modes. Android restarts activities during orientation changes for a reason. – Nathan Fig Sep 09 '11 at 02:35
  • It is still possible to set different layouts by this method. All we need to do is to check Orientation from new config. Put inside a condition statement. Do "setContentView(properlayout)". Anyway, I do agree with the fact that " Android restarts activities during orientation changes for a reason". But it is down to us to do what we want to achieve. Is it? – PH7 Sep 09 '11 at 02:51
  • 1
    If you handle rotation this way and call `setContentView` from `onConfigurationChanged`, state of your views is not saved and restored. If you have `EditView` for example, it's content will be reseted. – Salw Sep 09 '11 at 09:34
0

The mCurrentOrientation will be -1 if the app is starting for the first time.

static int mCurrentOrientation = -1;

public void onStart()
{
   int oldOrientation = mCurrentOrientation; 
   mCurrentOrientation = getCurrentOrientation(); 
   if ((oldOrientation != -1) && (oldOrientation != mCurrentOrientation)) {
       // Do your something here.
   }
}

If I understood your question correctly, I think this should work for you.

Ron
  • 24,175
  • 8
  • 56
  • 97