17

is it possible to detect screen rotation? I mean - rotation only, which is clearly distinguishable from activity initialization from another activity?

The onXxx methods seem not to be useful for this, I have tried adding/removing a flag from the starting Intent (the removing seems not to be reflected, on rotate the flag is there), and have tried adding android:configChanges="orientation" for the activity in the manifest, however the onConfigurationChanged method seems to be called every second rotation... wired.

I guess I am missing something... but haven't found clear solution in the other related threads.

Any ideas?

madhead
  • 31,729
  • 16
  • 153
  • 201
MerlinBG
  • 338
  • 1
  • 5
  • 16

3 Answers3

24

Manifest:

<activity android:name=".MyActivity" android:configChanges="screenSize|orientation|screenLayout|navigation"/>

Activity:

@Override
public void onConfigurationChanged(Configuration newConfig)
{
    Log.d("tag", "config changed");
    super.onConfigurationChanged(newConfig);

    int orientation = newConfig.orientation;
    if (orientation == Configuration.ORIENTATION_PORTRAIT)
        Log.d("tag", "Portrait");
    else if (orientation == Configuration.ORIENTATION_LANDSCAPE)
        Log.d("tag", "Landscape");
    else
        Log.w("tag", "other: " + orientation);

    ....
}

try this link also

How do I detect screen rotation

Community
  • 1
  • 1
kannappan
  • 2,250
  • 3
  • 25
  • 35
  • Thank you for the reply. However, I have tried it, before posting the question, and this does not work for me, no idea why, but the onConfigurationChanged is not called every time. It is called only when the orientation is becoming the same as the original (every second time). – MerlinBG Aug 01 '11 at 09:59
  • where are you testing it? Can you post your code? Cause I tested it on a phone and it worked – Finuka Aug 01 '11 at 10:21
  • I am testing it on the emulator and looking at the LogCat view. The code is 100% the same as posted above, without the orientation checks: android:configChanges="orientation|keyboard" in manifest (only for this activity) and @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); Log.d(" - ", "onConfigChanged"); // TODO remove } in the activity class... – MerlinBG Aug 01 '11 at 10:25
  • Additional info: here is the output in LogCat: `Activity first init: 08-01 10:50:11.920: DEBUG/-(279): onCreate 08-01 10:50:11.940: DEBUG/-(279): onStart First rotation: 08-01 10:51:13.420: DEBUG/-(279): onPause 08-01 10:51:13.450: DEBUG/-(279): onCreate 08-01 10:51:13.510: DEBUG/-(279): onStart 08-01 10:51:13.510: DEBUG/-(279): onRestore Second rotation: 08-01 10:52:37.970: DEBUG/-(279): onPause 08-01 10:52:37.980: DEBUG/-(279): onCreate 08-01 10:52:38.000: DEBUG/-(279): onStart 08-01 10:52:38.153: DEBUG/-(279): onConfigChanged` – MerlinBG Aug 01 '11 at 10:57
  • jum.. that's why...For me, it doesn't work on the emulator but it does on a real phone. Maybe you should see if there is any kind of bug about it... – Finuka Aug 01 '11 at 13:12
  • I found this: http://code.google.com/p/android/issues/detail?id=13189 seems like there is a problem in the emulator – Finuka Aug 01 '11 at 13:24
8

Use onConfigurationChanged method to detect the screen rotation isn't good idea. Configuration Change in this activity wouldn't works correctly when user rotate the screen.

So I use this solution to solve this problem.

public class SampleActivity extends AppCompatActivity {
    public static final String KEY_LAST_ORIENTATION = "last_orientation";
    private int lastOrientation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        if (savedInstanceState == null) {
            lastOrientation = getResources().getConfiguration().orientation;
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        checkOrientationChanged();
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        lastOrientation = savedInstanceState.getInt(KEY_LAST_ORIENTATION);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(KEY_LAST_ORIENTATION, lastOrientation);
    }

    private void checkOrientationChanged() {
        int currentOrientation = getResources().getConfiguration().orientation;
        if (currentOrientation != lastOrientation) {
            onScreenOrientationChanged(currentOrientation);
            lastOrientation = currentOrientation;
        }
    }

    public void onScreenOrientationChanged(int currentOrientation) {
        // Do something here when screen orientation changed
    }
}

But code still not good enough to use it in my project, so I applied this code to my own library (https://github.com/akexorcist/ScreenOrientationHelper).

compile 'com.akexorcist:screenorientationhelper:<latest_version>'

You can create base activity class like this

    public class BaseActivity extends AppCompatActivity implements ScreenOrientationHelper.ScreenOrientationChangeListener {
    private ScreenOrientationHelper helper = new ScreenOrientationHelper(this);

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        helper.onCreate(savedInstanceState);
        helper.setScreenOrientationChangeListener(this);
    }

    @Override
    protected void onStart() {
        super.onStart();
        helper.onStart();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        helper.onSaveInstanceState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        helper.onRestoreInstanceState(savedInstanceState);
    }

    @Override
    public void onScreenOrientationChanged(int orientation) {

    }
}

Then extend the activity with this base class

public class MainActivity extends BaseActivity {

    ...

    @Override
    public void onScreenOrientationChanged(int orientation) {
        // Do something when screen orientation changed
    }
}

Done!

Akexorcist
  • 2,287
  • 1
  • 16
  • 19
1

Why don't you try this?

in onCreated get the orientation of the phone:

Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
myOrientation = display.getOrientation();

then, override the method onConfigurationChanged and check if the orientation has changed:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    if(newConfig.orientation != myOrientation)
        Log.v(tag, "rotated");
    super.onConfigurationChanged(newConfig);
}

Don't forget to add into the manifest android:configChanges="orientation" in the activity.

Finuka
  • 730
  • 7
  • 15