How can make my android application to be Landscape or portrait but without the reverse directions?
Meaning that I want to enable SCREEN_ORIENTATION_PORTRAIT and SCREEN_ORIENTATION_LANDSCAPE but to disable SCREEN_ORIENTATION_REVERSE_LANDSCAPE and SCREEN_ORIENTATION_REVERSE_PORTRAIT.
Thanks
I had the same problem/feature request in my camera app, and found this post:
android camera surfaceview orientation
In changeRotation just comment ORIENTATION_PORTRAIT_INVERTED and ORIENTATION_LANDSCAPE_INVERTED, and create a method rotateViews(int degrees) to rotate all of the images(buttons) of your layout when switching between regular landscape/portrait.
Also,
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
worked better for me than
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR | ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
Make sure you notify the system that you want to handle orientation changes by adding "orientation" to the android:configChanges flag attribute in the activity tag in your manifest file.
Override Activity.onConfigurationChanged() and inspect the Configuration.orientation field in the passed Configuration parameter and set the orientation of the activity to either ActivityInfo.SCREEN_ORIENTATION_PORTRAIT or ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE using Activity.setRequestedOrientation appropriately.
Related
As my application supports only portrait mode for mobile devices.
As I select device Auto-rotate on.
But when I install this application on Google Pixel Android 10. It rotates in landscape mode.
As I mentioned in the manifest android:configChanges="screenLayout|keyboardHidden|screenSize|orientation".But still the WebView rotates in landscape mode.
How to handle this scenario.
Also when the device will rotate in landscape mode in onConfigurationChanged() method will return from the function.
Still, it rotates in landscape mode.
Please suggest to me.
Thanks
android:configChanges="screenLayout|keyboardHidden|screenSize|orientation"
fun onConfigurationChanged(){
if(Mobile){
return
}
Expected is The view should not rotate in landscape mode as it is supported for portrait mode only for the mobile devices.
In your manifest.xml file add following line to every activity declared: -
android:screenOrientation="portrait"
It will make sure that your application will be in portrait mode only.
android:configChanges="screenLayout|keyboardHidden|screenSize|orientation"
Above line will not prevent it to go to landscap mode. It will prevent view to regenerate and this how there is no need to save the states of the views.
To restrict app in portrait mode you should add below line in your activity tag.
android:screenOrientation="portrait"
Also the method onConfigurationChanged is called when configuration has been changed. Means after changing orientation it is being called so you can not write something inside of it to prevent activity to go into landscap mode.
Or you can try this
if(CommonUtils.dpFromPx(this, resources.displayMetrics.widthPixels.toFloat())>=600){
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
}
else{
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR
}
and the mothod dpFromPx is:
public static float dpFromPx(final Context context, final float px) {
return px / context.getResources().getDisplayMetrics().density;
}
What is Problem?
if app started as portrait then make activity as portrait , otherwise landscape , but don't detect sensor based or used based rotation otherwise.
My Solution:
Make variable isPortrait in application class and detect orientation in onCreate of Application class then use this variable in all activites to detect what orientation to use.
Problem in My Solution:
No Idea how can I change different configuration layouts and map them accordingly in this scenario , what if user change it orientation to landscape after app started in portrait ? is there any ActivityInfo flag to achieve this behaviour.
use this in your activity tag in manifest
android:configChanges="orientation"
android:screenOrientation="portrait"
In Mainfest within the atvitity tag add below code
android:configChanges="orientation|screenSize"
and in ur activity override onConfiguration method like below
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
log.e("onConfigurationChanged", "screen orientation change");
}
I have an app for Android, I want to force tablet (sw600dp and higher) to display in Landscape mode and phone to display in Portrait mode, so I handle in onCreate of my BaseActivity class
boolean isTablet= getResources().getBoolean(R.bool.isTablet);
if (isTablet) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
And the way I put "isTablet" in bools.xml file and put it in
values folder for phone
<resources>
<bool name="isTablet">false</bool>
</resources>
values-sw600dp for tablet
<resources>
<bool name="isTablet">true</bool>
</resources>
And in AndroidManifest I use
android:screenOrientation="nosensor"
just ensure to disable device orientation's sensor.
It seems to be my approach works fine (Landscape for tablet and Portrait for phone) BUT the problem happens when I run my app on Nexus 7 - my activities create twice. These steps are:
Hole Nexus 7 in Portrait (it's fine if I hold tablet in Landscape)
Then run the app
I find that the problem is the method setRequestedOrientation() (with 2 steps above). So I don't want to call that method anymore. I try to set orientation in AndroidManifest like:
android:screenOrientation="#integer/orientation"
Because:
SCREEN_ORIENTATION_LANDSCAPE = 0
SCREEN_ORIENTATION_PORTRAIT = 1
I declare "orientation" in integers.xml file and put it in
values folder for phone
<resources>
<integer name="orientation">1</integer>
</resources>
values-sw600dp for tablet
<resources>
<integer name="orientation">0</integer>
</resources>
Again, my approach tends to works fine BUT I find that AndroidMenifest just understands "orientation" in values folder, not in values-sw600dp folder. I don't want my activities to call 2 times. Did you have a problem like that?? Could you solve it? Thanks.
From the docs setRequestedOrientation(int):
If the activity is currently in the foreground or otherwise impacting
the screen orientation, the screen will immediately be changed
(possibly causing the activity to be restarted)
It's not being re-created, it's just being restarted to account for the change of orientation.
So just move the functionality that shouldn't be run twice to onCreate and you're done.
Simas answer is sort of correct, let me explain.
Let's say you are holding your device in a portrait position, you then start your Activity and in onCreate you call the following:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
Then, you are basically telling the device it should rotate (since you are holding the device in portrait mode).
But if you hold the device in landscape before launching your Activity and call the same as above, your device doesn't need to rotate since it is already in landscape mode.
As we all know, rotating your device causes the Activity to be destroyed and created again. The same goes for when calling setRequestedOrientation (if the device is currently not in the requested position).
So.. How to deal with it.
The first and most obvious option would be to not call
setRequestedOrientation. Instead handle your rotation by using
onSaveInstanceState to store your values and
onRestoreInstanceState to restore the values that were stored in
bundle, etc..
In my case, because of the design of my application, I had to use
setRequestedOrientation because I'm rotating the device based on the
selected video dimensions.
Here is how I accomplished this.
Since I want to handle rotation myself, I first had to add the
following in my manifest:
android:configChanges="orientation|screenSize|keyboardHidden"
By doing this you are overriding configuration changes. As
mentioned in the docs - This technique should be considered a last
resort
Next, I created a different layout for when I want to rotate the
device to landscape and called the following:
private void rotateScreen(Uri vidUri) {
try {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
Bitmap bmp;
retriever.setDataSource(this, vidUri);
bmp = retriever.getFrameAtTime();
videoWidth = bmp.getWidth();
videoHeight = bmp.getHeight();
if (videoWidth > videoHeight) {
setContentView(R.layout.activity_video_player_land);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
if (videoWidth < videoHeight) {
setContentView(R.layout.activity_video_player);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
} catch (RuntimeException ex) {
Log.e("MediaMetadataRetriever", "- Failed to rotate the screen");
}
}
Since everything in my portrait layout is in my landscape
layout, I do not have to worry about resources not being found.
The solution I went with will not work for all applications (if you have different resources for different orientations) but in my case, I use all the same resource, resized and moved around to better fit the landscape view.
In my case My screen orientation in manifest was portrait. I have changed it to landscape
android:screenOrientation="landscape"
then remove the line
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
from the onCreate block
This solved my problem. Sometimes the answer might be that easy
I am making an App which allow you read Wikipedia pages.
I want to display an icon each time when is phone is rotated from the portrait to landscape or vice versa. It will let user lock the screen orientation if he wants to or else the screen is oriented according to the sensor data. This is functionality is implemented by some of the App in the google play, for example - Pocket
To do this is i have overridden the
public void onConfigurationChanged(Configuration newConfig)
Now if i am setting the locked configuration by using( orientation_dir is the orientation value stored in the shared preferences and it is correct as i have debugged through the code for it.)
if(orientation_dir == Configuration.ORIENTATION_LANDSCAPE)
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}
else if(orientation_dir == Configuration.ORIENTATION_PORTRAIT)
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
then orientation is set correctly but then onConfigurationChanged() method is not called when the phone is rotated.
If i set the orientation this way
if(orientation_dir == Configuration.ORIENTATION_LANDSCAPE)
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
else if(orientation_dir == Configuration.ORIENTATION_PORTRAIT)
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}
then desired orientation is not set. Phone reset the orientation according to the sensor data.
I tried even by not calling the super in the method as i thought it might be setting it wrong but then it gives me the exception "Super not called".
I am trying for last 2 days and haven't got a any solution to this problem.
In general onConfigurationChanged() event fire only when an configuration change has occured. In your app the orientation changed event occurs only when the screen is free to rotate. If you have locked the screen orientation then the screen orientation event is not fired. onConfigurationChanged() does not listen to the sensor that is responsible to rotate the device but fires only when the appropriate event is happening.
So what you really want is to have access to a SensorManager and attach a SensorListener. This is the way for you to listen to the actual orientation of the device.
Here is a very nice demo that demonstrates the SensorManager capabilities with the orientation of the phone:
http://www.workingfromhere.com/blog/2009/03/30/orientation-sensor-tips-in-android/
UPDATE: The orientation sensor is a composite sensor to make things easier for the developer. It does not actually exist in the phone. Is a very neat sensor combining the accelometer sensor and the magnetic field sensor. And the OrientationSensor is currently deprecetated according to the docs (http://developer.android.com/guide/topics/sensors/sensors_position.html).
See What is the alternative to android orientation sensor? for sample usage.
it may need some fixing I have not tested it much.
onConfigurationChanged - is a notification to let your activity know the change in orientation.
You should not attempt to change or fix the orientation in that method. If you set the orientation to landscape or portrait then you will not get new orientation change notification because the orientation of the activity does not change. May be you should set the orientation setting in the event handler of the widget that you plan to show when there is a change in orientation.
Welcome all
I have a special need for my app. I must force the app to work only in portrait mode, but i need to know when the user has moved the phone to landscape mode. Why? because i am displaying a opengl view with a texture image, and when the user changues the phone position to landscape mode i must rotate the polygon without reseting the activity. Then i must force portrait mode on manifest, because i dont want that my onCreate method gets called again.
Please, can someone tell me how to achieve this?
I know how to rotate the image, i only need to know when the user has moved the phone to landscape position, but with portrait forced on manifest.
I tryed adding android:screenOrientation="portrait" in the manifest and also adding android:configChanges="keyboardHidden|orientation" to the declaration in the manifest; and then overriding onConfigurationChanged() in my activity. But this doens't works, because portrait mode is forzed, then onConfigurationChanged method is never called......
Thanks
Why not use the SensorManager to monitor when the phone has rotated 90 degrees. Actually this may be helpful also.
use this attribute in manifest android:configChanges="orientation" this stops recreating activity then override the onConfigurationChange() method. Give the same layout both in portrait and landscape mode. when orientation change occurs, that method wil be called then change the image as u like
Do Not set the screen orientation in the manifest (android:screenOrientation="portrait"). Add the android:configChanges="keyboardHidden|orientation", and override your onConfigurationChanged(). This way your onCreate will not be called twice.
Here a example of your onConfigurationChanged:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig); // tem que ter
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
} else
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
}
}