Activity not picking up the correct orientation - android

For my App, I need to fix the orientation to portrait on Phones and allow portrait and landscape on Tablets. I have looked at answers here and but I want to try to do the same using xml alone.
I tried adding the following line in my manifest
<activity
android:theme="#style/Theme.ActionBarLargeTitle"
android:name="com.work.activities.MyActivity"
android:screenOrientation="#integer/orientation_supported"
android:exported = "false"/>
In res/values/dimens.xml I added the following line (1 corresponds to portrait)
<integer name="orientation_supported">1</integer>
I have created another file, res/values-sw600dp/dimens.xml in which I have added (-1 corresponds to unspecified)
<integer name="orientation_supported">-1</integer>
On phone this code works fine and the Activity is always in portrait mode. On Nexus 10" Tablet(width 800dp) this fails and it is fixed in portrait mode. Is there anything wrong with this approach?
EDIT:
I have checked with various values and in all cases(in all devices) the value from res/values/dimens.xml is picked up. If this value is missing there is an error when the app is installed 'Installation error: INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION'.

The issue is you are using -sw600dp qualifier, which doesn't actually check orientation but rather checks that the shortest side is at least 600dp. Try using -land or -port qualifiers instead.

There are two possible problems here:
Make sure your tablet is reading from -sw600dp folder. I know it may sound weird for 800dp device. The easy way to check is to add a string with the same key in both folders and display in TextView.
Make sure your tablet understands -1 value. The phone I checked with did. Try changing to 0 and see if it forces landscape.

Related

How to use tablet-specific layout when in landscape mode?

I have defined a tablet-specific layout in the res/layout-sw600dp folder. Now. It loads correctly in tablet emulator and is checked and managed by code as expected. The problem is that I cannot access this layout variant to use in mobile emulator after I check that orientation is landscape. When I type in code R.layout., no hint is given as to the specific tablet layout, only one instance is given, activity_main. How can I use that tablet layout in the landscape orientation as well?
./app/src/main/res/layout-sw600dp/activity_filter.xml
./app/src/main/res/layout/activity_filter.xml
The "smallest width" qualifier doesn't care about device orientation. You'll have to make a copy of your layout and put it in the res/layout-land/ directory if you want that same layout on phones in landscape.
If you don't want to have two exact duplicate layouts (one in sw600dp and one in land), you can look into using a resource alias: https://developer.android.com/training/multiscreen/screensizes.html#TaskUseAliasFilters

dimens.xml(w840dp) not working

This seems like a bug but maybe I'm doing something really silly and just can't see it. I have these value files:
The integer value files are behaving as expected. Inside the default integers.xml I have:
<integer name="card_item_columns">2</integer>
and for the integers.xml(w840dp) I have:
<integer name="card_item_columns">3</integer>
But when it comes to the dimens files, only the sw600dp one seems to do anything. For the dimens.xml(sw600dp) I have this:
<dimen name="card_width">264dp</dimen>
and for the dimens.xml(w840dp) I have this:
<dimen name="card_width">400dp</dimen>
If I use a Nexus 7 emulator device in portrait it shows 2 columns. When I rotate it I see 3 columns as expected. This proves that it's at least 840dp wide as that integers.xml(w840dp) file is the only place it can get 3 columns from.
However if it's w840dp why doesn't it use the card width value in the dimens.xml(w840dp)? Is this not possible? Can a "w" qualifier not override an "sw" qualifier? I think it should.
I can adjust the value in the sw600dp file and the change is reflected, showing that it's getting called correctly from the layout file.
What basic concept am I not getting here? I find it hard to believe that there is a bug here. Surely if there was, other people would have noticed it. Spot the silly error to get some points. Or give me a clue that leads to the solution. Thanks.
The documentation on the Android site regarding resource qualifier precedence is pretty comprehensive:
Providing Alternate Resources
All other things being equal, smallestWidth has higher precedence than Available width
Configuration | Qualifier value
smallestWidth | sw<N>dp
Available width | w<N>dp

Issue when trying to fix orientation screen to natural or default orientation

I would like to lock the screen orientation specifying the configuration in the AndroidManifest, instead of doing it programmatically. So I've ended up with the following approach:
values/config.xml
<resources>
<integer name="orientation">1</integer>
</resources>
values-sw600dp/config.xml
<resources>
<integer name="orientation">0</integer>
</resources>
If I check the value’s resource programmatically
getResources().getInteger(R.integer.orientation)
I get the expected value: 0 for tablets and 1 for handsets, which is the value specified by the framework for landscape and portrait orientation respectively.
But if I use this resource in the AndroidManifest:
<activity
android:name="activities.InitialConfigActivity_"
android:noHistory="true"
android:screenOrientation="#integer/orientation" />
The activity always launches in portrait mode, regardless if it is a tablet or a handset device.
Any thoughts?
Thanks!
Edit: I originally read your question to mean you wanted complete control over the start-up orientation. If you are satisfied to get the natural/default orientation, then use nosensor as described below.
This may not qualify as an answer--I had more to share than could be put in a comment.
You've probably already looked at the discussion in these related issues: related-1, related-2, related-3.
In my experience, when an issue has been investigated by a number of different people for a period of four years, with no solution found, it usually means there is no solution.
One option might be to use the nosensor orientation in your manifest:
android:screenOrientation="nosensor"
This starts the activity in the device's "default" or "natural" orientation. On my devices this is: phone=portrait, 7-inch-tablet=portrait, 10-inch-tablet=landscape. Won't work for you if you want landscape for 7-inch tablet.
This post includes code for determining what a device's default orientation is.

How does Android determine which layout to use

So, I am aware that you can define different layouts for different screens and orientations. The problem I have is in grasping which will be used when.
I am considering three devices (as an example):
Google Nexus 7
Samsung Galaxy S3
Some really small phone.
At the start, there is a main.xml in res/layout which is the default layout to be used in portrait mode. Then, you can define main.xml in res/layout-land which is the default layout to be used when the phone is held in landscape mode.
These are the two layouts which will be used for Samsung Galaxy S3 and Nexus 7 and small phones because I have not defined anything specific.
Now, I want to define a layout, specifically for the small phone and portrait mode, in addition to the ones mentioned above. It will go under res\layout-small\main.xml
My question is: How will the layout for the small screen be chosen when it is held in landscape mode?
Links by #Simon are very useful. In addition to that the sample application NewsReader.zip on android's Supporting Different Screen Sizes page will help. If you read Use Orientation Qualifiers section it tell you what you want to do.
You can define all the layouts in an XML file in the res/layout/ directory. To then assign each layout to the various screen configurations, the app uses layout aliases to match them to each configuration. Eg. for small screen portrait a file:
res/values-sw600dp-port/layouts.xml:
Its contents can be like:
<resources>
<item name="main_layout" type="layout">#layout/small_screen_portrait</item>
<bool name="has_two_panes">false</bool>
</resources>
You can see the sample app for more. Hope this helps.

android:screenOrientation ? Can you go landscape only on high resolution devices?

Is there a technique to allow landscape only on large device?
I can set the manifest.xml file for the activity to rotate based on the sensor, eg
android:screenOrientation = "sensor" but this does not provide the behavior I'd like.
For instanced I'd like to allow a user to go to Landscape mode in a tablet device, but not on smaller resolution device (because the UI would look awful).
From what I can tell, there is no way to respond dynamically (eg at run time) if an orientation is acceptable. Or is there?
Am I missing something? Thanks in advance!
Could you do it with the resource folders:
For smaller landscape - default:
/layout/main.xml
main.xml root layout: orientation="portrait" (forcing portrait here instead of in the manifest)
For high res allowing portrait:
/layout-port-hdpi/main.xml
main.xml will be portrait hdpi only
This is the article you can get idea's from: ResourceTypes
Providing resources specific to large streens is built into the Android resource XML. Resource directories may be suffixed with -<suffix> to qualify that they are specific to a class of device capability, locality, time of day, and more. Specifically, you'd be interested in the screen size qualifier, which supports the values large and xlarge for just the purpose of creating special conditions for screens larger than 4 and 7 inches respectively.
For specifics on how to support multiple screen sizes, see this guide which comes directly from the developer manual.

Categories

Resources