I have an Activity with two layouts for landscape and portrait orientation. Everything works fine but! If I will lock a screen by power button, then press power button again, rotate device and unlock, my Activity will be empty. I have checked onCreate() method, onDestroy() and onResume(). If lock a screen and unlock without rotation everything will be ok and only onResume() will be called. But if unlock device with screen rotation methods onDestroy(), onCreate(), onResume(), onResume() will called (onResume() two times after rotate and after unlock).
I tried to use android:configChanges="orientation" - no result. Also I tried android:configChanges="orientation|screenSize" it is bad idea because after this activity will use only one layout depend on what orientation app was started
My device is Nexus 7 2013
Related
I have a layout that I am currently supporting orientation change by overwriting onConfigurationChanged and arranging views based on the selected orientation. Trying to support that same functionality by triggering it from a minimize/expand view button, but the orientation change getting called twice with the new and old orientations.
I have adjustConfig(int orientation) method that takes care about moving the views, hiding/showing what needed - it does the job.
#Override
public void onConfigurationChanged(Configuration newConfig) {
adjustConfig(newConfig.orientation);
super.onConfigurationChanged(newConfig);
//since fullScreeBtn blocks the orientation sensors, we enable it back
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}
}
public void adjustConfig (int orientation) {
// do some hide/show work based on the orientation type
}
fullScreeBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
setRequestedOrientation(
getResources().getConfiguration().orientation ==
Configuration.ORIENTATION_LANDSCAPE ?
ActivityInfo.CREEN_ORIENTATION_PORTRAIT :
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
});
I have a full-screen/minimize button that calls to
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) or
setRequestedOrientation(ActivityInfo.CREEN_ORIENTATION_PORTRAIT) based on the orientation I want to change and that triggers in turn onConfigurationChanged which handles my configuration, so far all good, but the problem is that for example, if I am on a portrait and clicking on the button to switch to landscape, the flow works and kicks off onConfigurationChanged with new landscape configuration which makes the change, but then immediately onConfigurationChanged gets called again with the current mode which is portrait and I end up with the initial state - portrait again.
EDIT: Currently the way the code works is you can either start with rotating physically the phone and switching back and forth between portrait and landscape either taping on the minimize/full screen, but not both, since the moment I call
setRequestedOrientation in the fullScreeBtn it forces the orientation and disables the sensor listening, so when I tap on full screen it rotates the screen as I want, then I would rotate the phone to see it, but from this point I am stuck as I can't rotate back physically, only by clicking on the minimize image again.
My goal is to have a support in both the sensors and the manual option, so if I click on fullScreeBtn it would switch to landscape mode and the user would need to rotate his phone to adjust a comfortable view ,exactly like YouTube does today.
You say:
the problem is that for example, if I am on a portrait and clicking on
the button to switch to landscape, the flow works and kicks off
onConfigurationChanged with new landscape configuration which makes
the change
but then immediately onConfigurationChanged gets called again with the
current mode which is portrait and I end up with the initial state -
portrait again.
I tried to replicate your case, but unless some details are missing, I can't see why point nr. 2 would happen. So after clicking on the button to switch to landscape the app stays like that in landscape - which is also what I was expecting.
Just to make sure no important details are left:
Are you listening by any chance to the OrientationEventListener in your app?
Do you have any logic in onConfigurationChanged that sets requested orientation?
UPDATE after additional info was added:
OK, now it makes sense.
Look, in order to achieve the behaviour you want, like in Youtube, most probably you will need to involve another component in the game, it's called: OrientationEventListener.
This listener allows you to listen to changes in orientation directly from the Sensor.
It does not matter if the Activity is locked in a specific orientation or not.
However, it's a bit more complex, this listener communicates the current orientation of device in degrees, from 0 to 359, you will have to figure out what range of degrees matches a landscape or portrait orientation.
The main idea is following:
The minimize/maximize button will lock the activity in a specific orientation, just as you do it right now.
Your implementation of OrientationEventListener will listen in background to the device orientation. When device orientation will match activity orientation, meaning the device is in landscape and the activity is also in landscape (or the other way around), you reset the activity orientation back to ActivityInfo.SCREEN_ORIENTATION_SENSOR. From this point on your Activity will not be locked in a specific orientation, but start following the sensor again.
Remove setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); from onConfigurationChanged() as now this step is handled as described above.
For beginning start looking into OrientationEventListener. There are examples on SO how to use it.
I have a WebView embedded in a Fragment. In the manifest file, I have declared that the activity will handle orientation changes:
android:configChanges="orientation|screenSize"
and in the Activity, I have over-ridden onConfigurationChanged() in order to capture the orientation.
I thought this means that we have to explicitly take care of any changes in the screen orientation. But what I see is that the screen is still rotated (although the activity is not re-created).
If I use the following line:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
it does prevent the screen from being rotated, but I don't get the rotation event.
So, in short, I don't want the system to rotate the screen, and at the same time, I want to get an event from the system that the orientation has changed from portrait to landscape.
Thanks,
Rajath
If you override onConfigurationChanged(Configuration newConfig), you should be able to handle the changes.
Thanks for editing the question, what you're after is now clear to me. I've got two suggestionsScreen orientation (i.e. portrait, landscape, reversePortrait, reverseLandscape, etc) just depends on orientation of the device in 3D space. So one idea is to capture the 3D orientation of the device yourself, which is the same information that the operating system uses to make the screen orientation decision. This means that you need to capture the accelerometer and the magnetic field sensor readings. One example of capturing that information is in my answer to Android Compass that can Compensate for Tilt and Pitch.Alternatively, you might try setting up a dummy activity that exists purely to capture the screen orientation information. That activity could sit on the activity stack behind your main activity. Although I'm not sure whether activities that aren't on top of the activity stack are notified of screen orientation changes.
I have this scenario where my activity launches in portrait mode (irrespective of current display's orientation) After my activity is closed, the device's display still remains in the same portrait orientation..
Is there a way to set it to the original (i.e. if the screen was in landscape, after my activity closes, it should go back to landscape) or should the Android System take care of this?
(And an important condition is that, my application's UI comes and goes off without any user interaction on screen)
I am facing this in ICS..
I have an application that can be viewed with landscape and portrait mode. I'm not using onConfigurationChanged() and android:configChanges="orientation|keyboardHidden" and the screen orientation change is working perfectly.
But now, i have a small problem. I want to learn to lock the screen orientation change of the screen. I mean that for example, when the user press a "lock" button, the screen orientation must be locked and it must not change, and when the user press again that button, the screen orientation must get unlocked
¿how can i lock the screen orientation dinamically?
For locking,
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
For unlocking,
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
where "activity" is your current Activity, in which you want to lock.
I have an activity which must always be launched in landscape mode. In my onCreate() method, I use the dimensions of the screen (width and height) to set up the interface, so it is important that the activity is not initially created with the wrong orientation.
To do this, I have the following in the manifest:
<activity android:name="app.myapp.WideActivity"
android:screenOrientation="landscape"
android:configChanges="keyboardHidden|orientation"
android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen"/>
This seems to work completely fine on my phone, but on my tablet (samsung galaxy tab, android 3.1) the activity is launched in portrait mode and switches orientation almost immediately (after the onCreate() method - it seems). On my phone (android 2.3) the screen is already landscape before the onCreate() method is called.
Putting setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
in the onCreate() method does't seem to help. How can I achieve what I'm trying to do?
I am not sure if you can fix the exact problem. It seems for me the problem is in samsung's implementation of activity/window management framework part.
However, you can try to prevent a crappy UI to appear by delaying the rendering.
In onCreate() show some default layout - just a plain black layout stretched to the entire screen.
In onResume() check the screen orientation, if it is not landscape then you post a delayed runnable which will apply your layout (setContentView(my_UI)).
Inside the runnable you also check if screen orientation is landscape, and re-post the runnable if orientation is still portrait, otherwise set the UI.