Physical keyboard orientation - android

I'm wondering if there's a way to figure out what kind of a physical keyboard ("portrait", like e.g. Droid Pro or "landscape", like e.g. HTC Mytouch Slide) device has?
I would like to automatically switch the activity orientation when the physical keyboard is activated so that the EditText in the activity is parallel to the keyboard.
I've tried a rotation/orientation solution from here, but on my test phone with landscape sliding keyboard I had to reverse Landscape and Portrait to make it work properly, which makes me think that on some devices it'll have to be other way around.
Comparing screen width and height, like some other answers there suggest, also seems iffy. Is there any other method perhaps?

It looks like there's no need to know the keyboard type: for the purpose of setting the correct orientation of the activity it seems to be sufficient to set it to sensor orientation from the onConfigurationChanged handler (which in turn is called when the physical keyboard is opened or closed):
#Override
public void onConfigurationChanged(final Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}

Related

Handling orientation from sensors and by triggering it manually

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.

How to get the orientation of my device when I have a fixed orientation in my Activity?

My Activity has a fixed orientation in Portrait and I want it to stay in portrait.
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
It would not make sense for the activity to do it responsive.
My Problem: I have a fragment in the application which contains a textView.
I want the fragment to be responsive so that the user can read the text.
I tried to get the orientation from the onConfigurationChanged Methode but this isn´t called when I turn my device since it always stays portrait.
Now I wanted to figure out the orientation of my device and then animate the fragment to turn it. But I have not found a way to get the orientation of my device but only the one of my Activity.
I also tried to set the fragment orientation with the methode above different than the orientation of the activity but that didn´t work (the orientation was always the same as the one of the activity.) .
Now I really don´t know what to do anymore.
Does anybody know how I can get the orientation of the device independent from the orientation on the Activity? -> or has an other idea how to solve my problem?
You can use the OrientationEventListener to get the orientation angle value.
OrientationEventListener listener=new OrientationEventListener(this,SensorManager.SENSOR_DELAY_NORMAL) {
#Override
public void onOrientationChanged(int orientation) {
Log.d(tag, "Orientation = "+orientation);
}
};
listener.enable();
Based on orientation value you can determine the orientation of the device.
You could read the android sensors directly to determine orientation: Sensors Overview
Hope this helps
(But I can't really understand why you would want to do this without rotating the activity..)

Faking landscape orientation in Activity when locked in portrait

The camera app on Android locks its orientation to portrait, and fakes an orientation change when you turn to landscape. The screen never re-orients itself (you don't see the screen reload or shift at all), but the icons turns to make it seem like it changed the orientation. How are they achieving this?
Let's say I did this. So I'm locked in landscape mode, and I rotate the phone so I'm in portrait (at least that's what it looks like to the user). Now if I have any dialog that pop up on top of this Activity, I'd want them to pop up in portrait orientation. How would I achieve this?

How can I make my android tablet app to look the same when it runs on phone in landscape mdoe

I have a android app layout for tablet. Its layout is 'landscape' based (i.e. it looks the way i want when I run on tablet (by default landscape).
But when I run the same app on a phone, android runs in portrait mode, (it squeeze my 'landscape' layout into a portrait ).
I have tried putting 'android:screenOrientation='landscape' in my activity in my Manifest file. But that does not fix it.
Basically, what I want is when I rotate the phone by 90 % (the width is > height), I want the phone layout looks the same as what i see on tablet (which is landscape by default).
How can I do that? android:screenOrientation='landscape' does not work.
Basically, I want some thing the game 'AngryBird', it always runs in landscape mode regardless it is phone or tablet and whether the phone is rotated.
I think you need to use 2 flags, not just one.
First is
android:screenOrientation='landscape'
Second is
android:configChanges="orientation"
First will tell android to run activity in landscape mode, where as second will tell android that do not change the orientation even when user rotates the phone. Basically with 2nd flag you are overriding orientation config changes.
Haven't done this myself, but instead of putting the main.xml layout in res/layout, try putting it in res/layout-land, so it will display this layout in landscape mode, and in res/layout-port, maybe a portrait alternative to main.xml?
Create folder \res\layout-land\ and place there your XML file with landscape layout. Phone choose between portrait and landscape layouts automatically.
Add this line in the onCreate method before you call setContentView:
setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE );

forcing landscape mode on a tablet

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.

Categories

Resources