Is there a way to make an application completely ignore a screen orientation change?
It is possible, quite easily, to override the default behavior and forbid a screen orientation change when the keyboard is open/closed.
Modifying the manifest
Open the manifest, switch to the Application tab and select the desired Activity you wish to override for the orientation change behavior.
Within Attributes you need to change two fields:
Screen orientation: select either portrait or landscape - whichever is desired. This will be the default layout.
Select events for Config changes you wish to override:
In this case these are keyboardHidden and orientation.
Modifying the Activity implementation
Now you need to override a single function within desired Activity.
Just add the function below to your Activity's class.
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
This is the default implementation if using the Source->Override/Implement Methods
menu option.
That's it! Now your orientation will always be kept.
Remember that this setting is per Activity - so you need to repeat this step for each Activity you wish to forbid the orientation change!
(Based on SDK 1.1)
You can make the same change in code with the following line (called in an activity):
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
Once you make this call, your application will stay in landscape (or portrait) mode. You can use the same call (with a different ActivityInfo enum) to make it sensitive to the orientation shifting again.
There's a full DevX article on the topic in Developing Orientation-Aware Android Applications.
(WARNING: since I've posted this link DevX has put up a registration wall.)
If you are setting either by AndroidManifest.xml or with the setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); you are going to run into issues with tablets. Their natural/default orientation is landscape.
If you truly want to completely ignore screen orientation changes I would use this setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR); value. I talk more about it in Stack Overflow question Android natural sensor orientation help.
Here is the xml:
<activity
android:name=".MyActivity"
android:screenOrientation="nosensor"
android:configChanges="orientation|keyboardHidden|keyboard"/>
You can define your activity in the AndroidManifest.xml file like this:
<activity
android:name=".MyActivity"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden|keyboard"/>`
In this case you should set the property for each activity. I didn't find an inline solution for all applications.
Add this to the activity:
android:configChanges="orientation|screenSize"
<activity android:screenOrientation="portrait"></activity>
You want to read the current orientation and keep it this way throughout all the activity's lifetime, so what I did is the following, at the end of onCreate:
// choose an orientation and stay in it
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
else if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Related
I am developing an app that needs to run strictly in portrait mode in smart phones and strictly in landscape mode in tablets. I am using the following code to set the orientation manually in onCreate method of my login activity:
if (getResources().getBoolean(R.bool.portrait_only)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}
Where the bool value comes false in Tablets. However the orientation is changed to landscape; still the layout file is picked from "layout_large" folder instead of "layout_large_land" folder. Hence my view looks stretched.
I have tried this link.
But it doesn't help.!
Any help is appreciated.
Thanks in Advance.
I had the same problem. Make sure you're NOT setting android:configChanges="orientation" for your activity in AndroidManifest.
I'm guessing the problem with that is that setRequestedOrientation potentially triggers an orientation config change, HOWEVER by using android:configChanges="orientation" this config change is not registered by the system.
Alternatively, if you want to keep the Manifest setting, you would have to implement your own recreation mechanic for this particular configuration change.
It may look something like this:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if(getResources().getBoolean(R.bool.portrait_only))
recreate();
}
I have used a folder like this for Tab & mobile
layout folder is for mobile and layout-sw720dp for Tabs. 720 dp is width which tells 720+ dp will use that folder for layout.
Being late in this thread but will help in the future SO. In my case I was programmatically changing the orientation of the screen by calling
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
OR
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
depending on the user's action. I have also created a separate layout for portrait and landscape but every time on changing the screen from portrait to landscape, it always loading the portrait screen in landscape.
In AndroidManifest.xml, I've set this
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
So, To solve this problem, Need to remove the orientation from android:configChanges then it works. This is what android documentation Link mentioned
The "orientation" value prevents restarts when the screen orientation
changes.
I'm working on an application that has an inline video player. I need to reproduce the fullscreen behavior of Youtube.
When the user goes to landscape rotating the device I catch it via onConfigurationChanged and make the corresponding layout modifications.
However, I also have a button to set fullscreen. I need this button to go to landscpe (ergo, fullscreen) but don't lock the orientation change via sensor.
Here is what I'm currently doing on onConfigurationChanged:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (this.isLandscape(newConfig.orientation)){
this.goToFullScreenMode();
}else{
this.goToInlineMode();
}
}
And here is what I'm doing in the button but failing because it locks the Activity in landscape:
this.getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
What I need is to go to landscape mode but allow the user to change back to portrait with the sensor, like Youtube does.
I can do it by just locking in landscape until the device is horizontal (by reading directly from the sensor) and then unlock the orientation again. I don't think this is the most "correct" way of doing it.
Greetings from the futuristic year of 2016.
The paths of life took me back to this same predicament on another Android application and I found out that the REAL answer to the problem was to simply add this...
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
...right after setting the orientation to the desired setting.
Here lies my own previous answer
Due to a lack of answers and because I was not abale to solve this in
an elegant way I finally ended using an OrientationListener to get the
raw degrees of the device.
With that I was able to release the user's orientation configuration
once the device was positioned like the actual layout.
If someone is interested in having more info about it just let me
know.
Create a layout-land directory in res and put the landscape version of your layout XML file in that directory.
or else put this line in your activity tag in manifest file
android:screenOrientation="landscape";
Try this..
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
Or in your manifest
<activity
android:name="Activity"
android:screenOrientation="landscape" />
Put this in ur Manifest for your Respective activity
<activity
android:name="YourActivityName goes here"
android:screenOrientation="landscape" />
I want to detect layout change in my activity while keeping the widgets where they are. Is there any way to do this. I tried setOrientation(LinearLayout.HORIZONTAL) and it doesn't seem to work. Any ideas?
Try to add android:configChanges="orientation" in your manifest file in the activity and you may be able to get the orientation in the onResume method of your activity by using
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
//WHAT TO DO IN LANDSCAPE
} else {
//WHAT TO DO IN PORTRAIT
}
As a lower level solution, you could use one of the Sensors, to detect the orientation/tilt of the device. If you don't want layout changes you can constraint your activity to portrait or landscape only in the manifest...
You can play with the app Elixir to see what values a specific sensor returns.
I am wondering how to switch off the orientation sensor completely in my android app for certain activities.
Here is what I struggle with. Let's say I set the orientation in the onCreate (or onStart/onResume) method of an activity dynamically with the following command.
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
What I experience is that screen is appearing on the display noticeable faster if I hold the device in a manner that would result in landscape mode according to the orientation sensor.
So what it feels like is as if the activity first wants to set the layout in the orientation as the sensor would suggest and thereafter it switches according to the setRequestedOrientation method. I even sometimes see this on the screen as described in a related post android - unexpected brief orientation change at switch of activity.
Seems like I am too late with the setRequestedOrientation call. So I am wondering how to switch off the the orientation sensor completely to avoid a setting of the orientation prior to the setRequestedOrientation call. Or as alternative, how to call setRequestedOrientation in time. As I need this feature dynamically as decided during runtime (preference settings) I cant set the orientation fixed in the manifest.
Thanks a lot in advance for any hint around this issue.
martin
Edit:
I forgot to mention, the manifest contains
android:configChanges="keyboardHidden|orientation|screenSize"
The performance impact happens because android kills your activity and then starts a new instance with the new configurations.
a good solution to this would be to handle configuration changes manually.
by
adding android:configChanges="orientation" to your activity element in the manifest file
Overriding onConfigurationChanged method in your activity to do the layout
another solution would be having tow activities , one works only in landscape the other in portrait by specifying orientation attribute in manifest file, and lunch the suitable one.
This is how you can set orientation at runtime as follows
int currentOrientation = getRequestedOrientation();
if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}
else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
I am displaying Timer on a screen .
After starting the Timer , I am changing the orientation from the portrait to landscape mode. In order to avoid the timer getting reset when changing from the portrait to landscape mode , I am adding the following code to the activity declaration in the manifest:
android:configChanges="orientation"
The problem I am facing is that , when the screen is switching from the portrait to landscape mode , the layout which gets displayed is same as portrait & not in landscape mode. Only a part of the screen of the landscape orientation is being occupied.
Is there any way by which we can avoid resetting the timer from changing from the portrait to landscape mode & also have a proper landscape layout?
Kindly provide your inputs.
Thanks in advance.
There is a simple way of doing this.
if you have two different layouts for landscape and portrait then let the android handle all the stuff for you. i mean do not override methods onConfigurationChange() method unless strictly required and do not add android:configChanges="orientation". just make different folders for portrait mode and landscape mode. viz. layout and layout-land....
To save present state of views use bundle. whenever orientation changes android reload activity and call onCreate() method. This saved bundle is passed in onCreate() method. Now you can retrieve views' state from this bundle.
now next question will be how to use this bundle. Then here is the quick example.
override onSavedInstanceState() method to save bundle.
Thanks.
Is there any way by which we can avoid
resetting the timer from changing from
the portrait to landscape mode?
Yes, store the value somewhere during onPause and read it during onResume.
Also have a proper landscape layout
Read up on Providing Resources, in particular table 2's "Screen orientation" section which also links to a very nice page about handling runtime changes.
All you need to do is make the manifest file set the screenOrientation="landscape"
<activity android:name=".main"
android:label="#string/app_name"
android:screenOrientation="landscape">
<intent-filter>
That turns off the auto sensor on only the form that you name to have landscape.