Android Tablet rotation question, switching Landscape to Portrait modes

3,045 views
Skip to first unread message

T500

unread,
Sep 12, 2012, 9:11:47 AM9/12/12
to kivy-...@googlegroups.com
Hi, Can you help with a newbie question?
Can or that is the best method of achieving orientation modes on a table like form landscape to portrait modes and vice versa on android ???
The mode is declared in 'android.txt', is this immutable. 
Is there a method to change this on the fly?

Any clues please?

Many thanks in advance

krister viirsaar

unread,
Nov 13, 2012, 2:21:11 PM11/13/12
to kivy-...@googlegroups.com
I now need this function as well. To specify, I don't need automatic orientation (though this would be better), I need one screen to be landscape and the other portrait.

is it possible and how do you do it?

T500

unread,
Nov 13, 2012, 9:02:10 PM11/13/12
to kivy-...@googlegroups.com
I think this my have been my first question to the group while suffering a complete documentation overload at the time of writing. A question so dumb no one bothered to answer it at the time:) 

I have yet to actually to write an app that requires auto rotation, but I think this is how I would approach it these days...

To detect the android rotation see... https://github.com/kivy/pyjnius , there are some examples reading the android sensors api.
Include "Android" in your "python-for-android" APK build.

You can use the kv size_hint and pos for when the screen is rotated. Since writing the original post kivy now supports Screenmanager which supports multiple kv file setups. Thus you can switch between bespoke layouts screen for portrait and landscape.

You can test your layout using http://kivy.org/docs/api-kivy.modules.keybinding.html. Use f11 to pc test the screen view in rotation modes.

To actually rotate the screen in program you can use the http://kivy.org/docs/api-kivy.core.window.html?highlight=window%20rotate  for setting the rotation angles 0, 90, 180 and 270 degrees.
 
Like I said, yet to put it all together, but I hope this helps.

Petr Vanek

unread,
Nov 14, 2012, 4:43:25 AM11/14/12
to kivy-...@googlegroups.com
On Wednesday, November 14, 2012 3:02:10 AM UTC+1, T500 wrote:
To detect the android rotation see... https://github.com/kivy/pyjnius , there are some examples reading the android sensors api.
Include "Android" in your "python-for-android" APK build.



Wouldn't it be better to bind to the rotation event of the android, rather then consume power and CPU o calculating orientation? This is what i found:

@Override
public void onConfigurationChanged(Configuration newConfig) {
   
super.onConfigurationChanged(newConfig);
       
int nCurrentOrientation = _getScreenOrientation();
    _doSomeThingWhenChangeOrientation
(nCurrentOrientation);
}


private int _getScreenOrientation(){    
   
return getResources().getConfiguration().orientation;
}

Now, there are several alternative methods for this, but this would be a good start, but i have no idea how to subscribe to a java even via jnius...  :(

krister viirsaar

unread,
Nov 14, 2012, 5:02:32 AM11/14/12
to kivy-...@googlegroups.com
wow this stuff is complicated. I'll start with just rotating the window and work myself up from there.

Petr Vanek

unread,
Nov 14, 2012, 5:06:53 AM11/14/12
to kivy-...@googlegroups.com
On Wed, Nov 14, 2012 at 11:02 AM, krister viirsaar <krister....@gmail.com> wrote:
wow this stuff is complicated. I'll start with just rotating the window and work myself up from there.

--
 
 

rotation is easy, you'll need Window:

from kivy.core.window import Window

then in build (besides your code), bind it:

def build(self):
        Window.bind(on_key_down=self.on_key_down)

and then rotate:

def on_key_down(self, instance, code, *largs):
    print code
    Window.rotation+=90

Now we need to autorotate :)

Petr Vanek

unread,
Nov 27, 2012, 5:30:46 PM11/27/12
to kivy-...@googlegroups.com
I have been trying to progress with the screen rotation and I am looking at this example from pyjnius:

from jnius import autoclass
DisplayMetrics = autoclass('android.util.DisplayMetrics')
metrics = DisplayMetrics()
print 'DPI', metrics.getDeviceDensity()

but the
getDeviceDensity() doesn't exist. Is it src/src/org/renpy/android/Hardware.java dependent?

>>> print 'DPI', metrics.getDeviceDensity()
DPITraceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'android.util.DisplayMetrics' object has no attribute 'getDeviceDensity'


any of these:
>>> dir(metrics)
['DENSITY_DEFAULT', 'DENSITY_DEFAULT_SCALE', 'DENSITY_DEVICE', 'DENSITY_HIGH', 'DENSITY_LOW', 'DENSITY_MEDIUM', 'DENSITY_TV', 'DENSITY_XHIGH', 'DENSITY_XXHIGH', '__class__', '__cls_storage', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__javaclass__', '__javaconstructor__', '__module__', '__new__', '__pyx_vtable__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'density', 'densityDpi', 'equals', 'getClass', 'hashCode', 'heightPixels', 'noncompatDensity', 'noncompatDensityDpi', 'noncompatHeightPixels', 'noncompatScaledDensity', 'noncompatWidthPixels', 'noncompatXdpi', 'noncompatYdpi', 'notify', 'notifyAll', 'scaledDensity', 'setTo', 'setToDefaults', 'toString', 'wait', 'widthPixels', 'xdpi', 'ydpi']

just return 0 :

>>> metrics.xdpi
0.0
>>> metrics.density
0.0

I have been trying to get screen layout without the event yet, just like this:

Configuration = autoclass('android.content.res.Configuration')
Configuration().orientation

but again, it always returns zeros...?

What am i doing wrong?

thank you

Petr

Petr Vanek

unread,
Nov 28, 2012, 5:48:49 PM11/28/12
to kivy-...@googlegroups.com
OK, i can now get the metrics to work:


metrics = DisplayMetrics()
print 'DPI', metrics.getDeviceDensity()

after setting the object to some default values:

metrics.setToDefaults()


the Configuration object should work the same: You must call setToDefaults() for this object to be valid.

So i try:

Configuration = autoclass('android.content.res.Configuration')
Configuration.setToDefaults()
conf=Configuration
conf.orientation
60

but this is not right as the "60" is some kind of index number...

i have tried all combinations but no luck...
Petr

T500

unread,
Nov 28, 2012, 10:13:28 PM11/28/12
to kivy-...@googlegroups.com
Hi, just been looking at Androsensor, an app for looking at the Android sensor data. https://play.google.com/store/search?q=Fiv+Asim
But in the help it offers a tantalising clue as to what you are actually reading. It reads...

"ORIENTATION: Shows which way your phone is pointing at. X is relative to magnetic north pole (0 means your devices top points to the north pole, like a compass). Yis relative to the ground (0 means left flat, eg on a table. 90 means the that the phone is standing vertical) and Z shows roll, rotation where 0 means phone is facing the sky and 180 means screen is facing the ground.

The orientation sensor is not a real sensor, but a software sensor which sets it values from combining accelerometer and magnetic fields values and applying certain calculations. In android 4.0 ICS the gyroscope also is a part in the calculations to improve accuracy." 

Electronically this makes a lot of sense as gyros would spin up on startup with no external reference's to be calibrated by. The accelerometer detects the force of gravity thus 1g present is down and level roll. The compass provides the direction, gps provides were you are so you now know which up and how fast your moving or not in a given direction.

So using the app I did a quick test of the Y value, which on mine is a min value of -81 when upright and a max of 81 when upside down. But its a value of around zero for 270 or 90 degree's. There is no way of discerning if it was a clockwise or counter-clockwise rotation. Which if means if Im reading this correctly the value is the same for 45 degree lean to the left as it is for the right. Which to me sounds like its defeating the object as you would still need a gyro or accelerometer reference to determine which way it moved?   

I do know electronically speaking the gyro and accelerometer output is relative. I think the orientation is a frame of reference and not the actual angle of the device that we seek. But I will give it a try and venture in to the pyjius datastorm, I maybe sometime!

 

Petr Vanek

unread,
Nov 30, 2012, 3:33:34 PM11/30/12
to kivy-...@googlegroups.com
Thank you but this didn't help me. The values i saw was some kind of bogus and up till now i haven't been able to read anything sensible from the
android.content.res.Configuration . Still, rotation is imho very important feature and i will try to get through this...

Petr

T500

unread,
Nov 30, 2012, 8:46:12 PM11/30/12
to kivy-...@googlegroups.com
I tried the Pyjnius accelerometer as in the test example today. Interesting result, sane values from 9 to 0 to -9 back to 0 for x, y and z. Not the expected reflective values. It works, I can use this for a rotate. My sling together test prog shows dpi and the 3 accelerometer values on to the text of 4 buttons, crude but effective to expand the code with. Not pretty but it got the job done....

'''
Demo App
'''
import sys
import kivy
kivy.require('1.4.0')
from kivy.config import Config
from kivy.app import App
from kivy.properties import ObjectProperty, NumericProperty
from kivy.clock import Clock
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.label import Label

if sys.platform == "linux3":
    from jnius import autoclass

class rott(Widget):
    pass

class demo(App):
    # Create an instance of my App
    #
    ticker = NumericProperty(0)
    
    def build(self):
        if sys.platform == "linux3":
            self.Hardware = autoclass('org.renpy.android.Hardware')
            self.Hardware.accelerometerEnable()
        self.app = rott()
        Clock.schedule_interval(self.counter, timeout=.1)
        return self.app 
        
        
    def counter(self, event):
        self.ticker = self.ticker+1 
        
        if sys.platform == "linux3": 
            self.app.btxt1.text = str(self.Hardware.getDPI())
            self.acc = self.Hardware.accelerometerReading()
            self.app.btxt2.text = str(self.acc[0])
            self.app.btxt3.text = str(self.acc[1])
            self.app.btxt4.text = str(self.acc[2])
if __name__ in ('__android__', '__main__'):
    MyApp = demo()
    MyApp.run()

This demo crashes after a few minutes, I'm not using Hardware.accelerometerDisable() which I suspect is causing some kind of buffer overrun error. I would be interested to know if the values are between 9 and -9 for all devices?
Reply all
Reply to author
Forward
0 new messages