Disable landscape orientation for phones but allow for tablets - java

So the general consensus is this; most people use their phones in portrait and most people use their tablet in landscape. Depending on which activity it is my app's layout goes crazy when you rotate on the phone to landscape and it just wouldn't be worth the time to fix considering users are unlikely to rotate here and have no reason to do so. I'm aware of the ole orientation="portrait" trick in the Manifest in the activity element, however this locks tablet users into portrait which wouldn't be appropriate. I would like to disable portrait on all my activities for tablet users yet simultaneously disable landscape on most all my activites for phone users. I tried to pull a fast one by making a layout-large-land folder and no layout-large folder, but that doesn't prevent the orientation from changing on tablets.

If you just use setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) from code you will catch interesting effect on Android 26+. If the system autorotation option is enabled and you hold phone in landscape orientation and start new Activity it will appears in landscape orientation and then rotate to portrait in a few seconds. You doesn't catch such effect if set android:screenOrientation="portrait" option in the AndroidManifest. But there are not way to have different rotation option into AndroidManifest for phone and tablet.
There's way to solve that if you wish lock portrait orientation on phone and unlock autorotation on tablet.
Set option android:screenOrientation="locked" in the AndroidManifest for each Activity in you project.
<activity android:name=".SomeActivity"
android:screenOrientation="locked" />
where "locked" – Locks the orientation to its current rotation, whatever that is. Added in API level 18 from Android docs
Then set in parent BaseActivity such code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
int orientation = getResources().getConfiguration().orientation;
if (isTablet()) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
} else if(orientation != Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
There are a few ways to detect that current device is Tablet. Choose implementation of isTablet() method yourself.

I guess you can use a code like this in onCreate() method:
int screenLayoutSize = getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
if (screenLayoutSize == Configuration.SCREENLAYOUT_SIZE_SMALL || screenLayoutSize == Configuration.SCREENLAYOUT_SIZE_NORMAL) {
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
And don't specify any orientation in xml, so by default it switches in both mode.

My suggestion would be to first find the way to know at run-time whether the activity is being executed in a Tablet by invoking a resource as explained in this answer. Then set the orientation as explained in this answer.

-Do One thing put this on the in the res/values file as bools.xml or whatever (file names don't matter here):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">true</bool>
</resources>
and Put this one in res/values-sw600dp and res/values-xlarge:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">false</bool>
</resources>
and then into java class file write this below code in onCreate method:
if(getResources().getBoolean(R.bool.portrait_only)){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
Devices that are more than 600 dp in the smallest width direction.
see the below link for the how to add directories and file into android studio project

Related

How to be device specific when running layout and layout-w720dp?

I happen to have an activity with different layouts for a phone and a tablet as res/layout/activity_main.xml and res/layout-w720dp/activity_main.xml. Now I want it to be device specific and not run the tablet version of the activity on all tablets. Is there a way I can specify that in setContentView(R.layout.activity_main) or should I rename my activities for the phone and the tablet and use the following instead?
if (isTablet) {
setContentView(R.layout.activity_main_tablet);
} else {
setContentView(R.layout.activity_main_phone);
}

I want my game to stay fixed on Portrait how can i do this?

So I wanted to see how my project looks like when in landscape and for sure i didnt like the appearance. I was wondering how can i make my project stay on portrait? I will appreciate any help.
android.app.FragmentManager myFragment = getFragmentManager();
FragmentTransaction fragmentTransaction = myFragment.beginTransaction();
Configuration configInfo = getResources().getConfiguration();
if(configInfo.orientation ==Configuration.ORIENTATION_LANDSCAPE){
FragmentLandscape lScape = new FragmentLandscape();
fragmentTransaction.replace(android.R.id.content,lScape);
}else{
FragmentPortrait lportrait = new FragmentPortrait();
fragmentTransaction.replace(android.R.id.content,lportrait);
}
fragmentTransaction.commit();
There are multiple ways to force portrait mode, but my preferred way to do so is the to use the following code for each activity inside AndroidManifest.xml
android:screenOrientation="portrait"
Later on, if and when you decide to create an alternate landscape layout for tablets, you can change those same lines in AndroidManifest.xml to this:
android:screenOrientation="nosensor"
The "nosensor" setting tells your app to use the natural orientation for the device, and will not change if the user rotates the device. So tablets will always use landscape orientation for your app, and phones will always use portrait orientation.

Android takes xml only from portrait layout folder

I have created two XML files for portrait and landscape mode separately and kept them in folders layout and layout-land respectively.
Note: I have given android:launchMode = "singleTask" in manifest file for that activity for some reason.
Issue: In both portrait and landscape mode, it takes xml from layout folder.
What is the reason for taking xml only from portrait layout folder? Is it because of the "single task property"?. What am I missing in this?
Thanks in advance.
Normally, when you change orientation, configuration change event is fired, your activity is destroyed and recreated in the new layout. When it's recreated, the corresponding, portrait or landscape, layout is used.
Because you indicate that you explicitly handle orientation changes, the activity is not destroyed/recreated on orientation change - and therefore the layout is not changed. To achieve what you want, you need to store the original orientation when the app starts and then handle orientation changes in your code, something like this:
private int currentOrientation;
public void onCreate(Bundle sis) {
...
currentOrientation = getResources().getConfiguration().orientation;
}
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if(currentOrientation != newConfig.orientation) {
//re-set the layout into your activity
setContentView(R.layout.my_layout);
currentOrientation = newConfig.orientation;
}
}
Depending on your logic, you may want to get values from existing views and re-set them after re-setting the layout.

android activity restarted when orientation changes

I read many posts about this problem like [this link][1] and one solution is add orientation configChanges to manifest and handle onConfigurationChanged event in order to prevent onCreate activity to be called again when rotation. I did it and event is triggered properly, however, after this execution, onCreate method is also executed! why? what I am missing? Thank you
manifest,
<activity
android:name="webPush"
android:configChanges="keyboardHidden|orientation"/>
activity,
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setContentView(R.layout.vistaaib);
}
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.vistaaib);
...
I think this will work.........
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name">
Beginning with Android 3.2 (API level 13), the will "screen size" also changes when the device switches between portrait and landscape orientation. Thus, if you want to prevent runtime restarts due to orientation change when developing for API level 13 or higher you must use
android:configChanges="orientation|screenSize"
I Did this.
I added This code to manifest and it works perfect.
<activity
android:name="?"
android:label="#string/?"
android:theme="#style/?"
android:configChanges="orientation|screenSize">
You will need to add this under you activity if you want to change something when the device is rotation.
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}
Write this two lines of code in manifest file in that Activity.
Seem this will solve your problem.<activity
android:name=".YourActivity"
android:configChanges="orientation|keyboardHidden"/>
Your activity will be restarted on any configuration change. Most likely it is being restarted because the keyboard state changes. Try adding this to the activity's attributes:
android:configChanges="orientation|keyboard|keyboardHidden"
If you are working for API level 12 or lower
In menifest file, put following just after declaring your Activity Name.
android:configChanges="orientation"
e.g.-
<activity
android:name=".NameOfYourActivity"
android:configChanges="orientation"/>
And in android 3.2(API level 13) or higher version screen size also changes on rotation changes so declare this too.
for this,
android:configChanges="orientation|screenSize"
Following Could be the reason
Event :screenSize
The current available screen size has changed. This represents a change in the currently available size, relative to the current aspect ratio, so will change when the user switches between landscape and portrait. However, if your application targets API level 12 or lower, then your activity always handles this configuration change itself (this configuration change does not restart your activity, even when running on an Android 3.2 or higher device).
Added in API level 13.
so along with "orientation" add "screenSize" as well

Android onConfigurationChanged not being called

I am having trouble with telling Android to not call onCreate() when the orientation changes. I have added android:configChanges="orientation" to my manifest but still when the orientation changes onCreate() is called. Here is my code.
AndroidManifest.xml
<activity android:name="SearchMenuActivity" android:theme="#android:style/Theme.NoTitleBar" android:configChanges="orientation"></activity>
SearchMenuActivity.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the current layout to the search_menu
setContentView(R.layout.search_menu_activity);
Log.d(TAG, "onCreate() Called");
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
//don't reload the current page when the orientation is changed
Log.d(TAG, "onConfigurationChanged() Called");
super.onConfigurationChanged(newConfig);
}
And my LogCat Output
06-23 12:33:20.327: DEBUG/APP(2905): onCreate() Called
//Orientation Changes
06-23 12:33:23.842: DEBUG/APP(2905): onCreate() Called
Does anyone know what I am doing wrong? Thanks.
This was my gremlin for the ~same problem:
Caution: Beginning with Android 3.2 (API level 13), the "screen size"
also changes when the device switches between portrait and landscape
orientation. Thus, if you want to prevent runtime restarts due to
orientation change when developing for API level 13 or higher (as
declared by the minSdkVersion and targetSdkVersion attributes), you
must include the "screenSize" value in addition to the "orientation"
value. That is, you must decalare
android:configChanges="orientation|screenSize". However, if your
application targets API level 12 or lower, then your activity always
handles this configuration change itself (this configuration change
does not restart your activity, even when running on an Android 3.2 or
higher device).
(From http://developer.android.com/guide/topics/resources/runtime-changes.html)
TL;DR: add "|screenSize" to android:configChanges="orientation" for API 14+
A couple of things to try:
android:configChanges="orientation|keyboardHidden|screenSize" rather than android:configChanges="orientation"
Ensure that you are not calling setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); anywhere. This will cause onConfigurationChange() to not fire.
Check that you are not using android:screenOrientation in your manifest.
If none of that works, read through the Android doc on handling runtime changes and make sure you are doing everything correctly. There may be something somewhere else in your code that's causing the problem. http://developer.android.com/guide/topics/resources/runtime-changes.html
EDIT: As derrik pointed out, I assumed that you were changing the configuration with the accelerometer detecting what way the device was facing. If you want the configuration to change as the keyboard is shown/hidden the configChanges in the manifest must include keyboardHidden as well.
Try use this one.....
android:configChanges="orientation|keyboardHidden|screenSize"
You should change the configChanges entry in AndroidManifest.xml to:
android:configChanges="keyboardHidden|orientation"
Otherwise, sliding the keyboard doesn't trigger onConfigurationChange() even though the orientation changes. I just tested this on my HTC Desire Z.
Add this to your manifest to each activity.
android:configChanges="keyboardHidden|orientation|screenSize"
Then, override onConfigurationChanged on your activity as such
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
Manifest:
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize">
</activity>
Activity & Fragment:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d(TAG, "onConfigurationChanged " +
(newConfig.orientation
== Configuration.ORIENTATION_LANDSCAPE
? "landscape" : "portrait"));
}
Output:
10-29 21:53:26.951 D/FragmentOne: onConfigurationChanged landscape
10-29 21:53:26.951 D/MainActivity:onConfigurationChanged landscape
It wasn't triggering in my Fragment (Fragments aren't registered in the AndroidManifest.xml) so I had to move it to the Activity managing my Fragment, in my case the TabsPagerActivity.
Few things can be cross check:
In my case I was tracking language change of device using the onConfigurationChanged.
Few things need to know about onConfigurationChanged is there is some difference in behavious between onConfigurationChanged of Activity and Application.
When you change the configuration of device the Application level onConfigurationChanged will be call automatically and immediately but onConfigurationChanged of activity will call when you navigate to that activity.
and another thing is only locale in manifest will not work sometime So you have declare other config change event along with the locale(in my case) that should be like android:configChanges="layoutDirection|locale"

Categories

Resources