5

I have to solve the following: I have an Activity which's android:screenOrientation="portrait". Even though, when the device is rotated to landscape while this Activity is visible, I have to start another one, and, when the device is rotated back to portrait, I have to finish() the activity in landscape. I tried to perform this with a BroadcastReceiver, but this special activity doesn't receive any broadcasts because of the android:screenOrientation="portrait". Any help is well appreciated.

Thanks.

overbet13
  • 1,654
  • 1
  • 20
  • 36

7 Answers7

8

Philipp's solution in Get phone orientation but fix screen orientation to portrait work's perfectly for me:

You can use the SensorManager class to get the orientation of the Android device, even when the automatic orientation switching is disabled in the Manifest by android:screenOrientation="portrait"

See this code (by Philipp, see link above):

SensorManager sensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
    sensorManager.registerListener(new SensorEventListener() {
        int orientation=-1;;

        @Override
        public void onSensorChanged(SensorEvent event) {
            if (event.values[1]<6.5 && event.values[1]>-6.5) {
                if (orientation!=1) {
                    Log.d("Sensor", "Landscape");
                }
                orientation=1;
            } else {
                if (orientation!=0) {
                    Log.d("Sensor", "Portrait");
                }
                orientation=0;
            }
        }

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

        }
    }, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
Community
  • 1
  • 1
Wile E. Genius
  • 185
  • 2
  • 15
5

When android:screenOrientation="portrait" or "landscape" are set in the menifest file no listeners are fired still if u want to do it try handling the portrait only mode in ur onConfigurationChanged() programatically and here u will also be able to start the activity again.

Chandrashekhar
  • 498
  • 4
  • 19
1

You can always find out your orientation using sensors;

public static final int PORTRAIT        = 0;
public static final int PORTRAIT_REV    = 2;
public static final int LANDSCAPE       = 1;
public static final int LANDSCAPE_REV   = 3;

private final SensorEventListener mListener = new SensorEventListener() {

   public void onSensorChanged(SensorEvent event) {


            azimuth = event.values[0];
            pitch   = event.values[1];
            roll    = event.values[2];

            {
                if (pitch < -45 && pitch > -135) {
                    orient = PORTRAIT;
                } else if (pitch > 45 && pitch < 135) {
                    orient = PORTRAIT_REV;
                } else if (roll > 45) {
                    orient = LANDSCAPE;
                } else if (roll < -45) {
                    orient = LANDSCAPE_REV;
                }

            }

           // if(orient!=lastOrient && !orientChanging)
           // {
           //   orientChangeStart = System.currentTimeMillis();
           //   orientChanging = true;
           // }
}
ZZZ
  • 678
  • 2
  • 10
  • 26
  • Did you try this piece of code before you sent it? Also, I would rather see some documentation... – overbet13 Sep 10 '12 at 06:30
  • azimuth, pitch and roll have no types, just as orient, plus, you don't register the listener to anything, you don't enable it, and so on. Not to mention that SensorEventListener has another method you must implement in order to create an object from this interface. Sorry, but I need correct answers according to some official documentation. – overbet13 Sep 10 '12 at 09:47
1

after a little struggle the best way i found was using OrientationEventListener like so:

private void addOrientationListener()
    {
        OrientationEventListener listener=new OrientationEventListener(getActivity(), SensorManager.SENSOR_DELAY_UI)
        {
            public void onOrientationChanged(int orientation) {

                if( (orientation>=230 && orientation<=290) || (orientation>=70 && orientation<=90))
                {
                    isLandscape=true;
                }
                else if(orientation==-1){
                    //KEEP THE CURRENT SATTE
                }
                else
                {
                    isLandscape=false;
                }
            }
        };
        if(listener.canDetectOrientation())
            listener.enable();
    }

you should call disable() on OnPause()

Gal Rom
  • 6,221
  • 3
  • 41
  • 33
0

Have you used Orientation Listener? I'm not sure if that's exactly what you need, but I'm gathering that you want to find out when the orientation is changing back and forth:

http://developer.android.com/reference/android/view/OrientationListener.html

Wait what
  • 90
  • 1
  • 8
  • Did you try this? When you try this method, you will see that the callback of the orientation listener is called lots of times, even on the slightest moves. This was not an option for me. – overbet13 Sep 06 '12 at 05:22
  • I mean this could help, but I need to write an algorithm to process data from the callback, for which I don't really have the time. – overbet13 Sep 06 '12 at 05:25
  • Why wouldn't 'onOrientationChanged (int orientation)' work for you? With an argument of 90 or 270 degrees, it would detect only the changes when it turns on its side. Is that not what you were looking for? http://developer.android.com/reference/android/view/OrientationEventListener.html#onOrientationChanged(int) – Wait what Sep 06 '12 at 17:06
  • btw, OrientationListener is deprecated. – overbet13 Sep 07 '12 at 05:49
  • it still works though right? or OrientationEventListener? Did they work for you or not? – Wait what Sep 07 '12 at 17:25
0

The class that you need to use is the OrientationEventListener, assuming that you can detect rotation. If you force the screen into a specific orientation using android:screenOrientation="portrait", these events won't be fired.

Instead, I'd recommend making two layout.xml files and use configuration qualifiers to determine which one should be displayed. (http://developer.android.com/guide/practices/screens_support.html)

res/layout-land/my_layout.xml
res/layout-port/my_layout.xml

Then use the OrientationEventListener to detect when the screen is rotated. When the screen is rotated from landscape to portrait, you can finish(); or call whichever functions you'd like.

Best of luck!

SD_Guru
  • 339
  • 3
  • 10
  • I have an activity, in which I have a view flipper. And I want to allow the device to show a landscape view if and only if a specific child of the view flipper is on top. This means I only want to catch the landscape event if the user is on a specific view. I don't want the other views (and the whole activity) to be recreated on rotation. – overbet13 Sep 06 '12 at 05:28
  • The logic should be the exact same, only create layout-land/ and layout-port/ versions of the specific child view. If you can use the OrientationEventListener to capture the event, you can manually re-inflate the child view in that manner as well. – SD_Guru Sep 06 '12 at 16:57
  • Just try to use an OrientationEventListener on a device, try to rotate it, and see the result. Then try to explain that, thanks. – overbet13 Sep 07 '12 at 06:23
0

You can do it in a couple of ways, one is listening to broadcast messages as discussed in other posts and the other option is as follows.

Set the android:configChanges="orientation" in the manifest for the activity which will give you control over the orientation change. By doing so you can override the onConfigurationChanged() method and start your new activity activity.

Gan
  • 1,349
  • 2
  • 10
  • 27