Screen orientation

1,527 views
Skip to first unread message

Ratamovic

unread,
Nov 13, 2011, 4:12:45 AM11/13/11
to android-ndk
Hi all,


I am currently trying to deal with screen orientation and sensors in a
NativeActivity. Some of these issues are not specifically NDK related
but I am interested in solving them from native code (even if I have
to use JNI callbacks).


What I know:
- One need to detect screen rotation on the basis of its natural
orientation to handle properly devices which can be, by deault, in
either landscape or portrait orientation (see
http://android-developers.blogspot.com/2010/09/one-screen-turn-deserves-another.html).

- A good way to convert from natural orientation to screen orientation
is to swap or invert axis as explained in NVidia doc:
http://developer.download.nvidia.com/tegra/docs/tegra_android_accelerometer_v5f.pdf.

- When orientation change of 90°, application is recreated.
Orientation can be detected when application starts

- But when orientation changes of 180°, configuration does not change
and no event is fired


What I would like to know:
- Is there a proper API to perform Display.getOrientation() natively.
Currently, the only solution I see relies on JNI. Through the
AConfiguration API (e.g. AConfiguration_getOrientation), we can only
detect if application is in portrait or landscape but not reversed
portrait or landscape.

- How to detect if a device orientation change of 180° happen apart
from polling regularly the orientation (through JNI :)?).

- Is it possible to fix orientation to Landscape or Portrait (both at
the same time in an) but not reverse Landscape or Reverse Portrait. In
the Android manfest, we can use portrait, landscape but not both at
the same time. My guess is that we have to handle it ourselves with
android:configChanges but configuration does not include "reverse"
information...


My conclusion to all of this is that when dealing with sensors,
orientation should be fixed and handled manually if absolutely
required (although detecting rotation according to natural orientation
is still necessary)... Am I wrong?

Thanks in advance

mikelong

unread,
Aug 23, 2012, 11:32:56 AM8/23/12
to andro...@googlegroups.com
Is it just me or is anyone else still having trouble getting this to work from native code?

By following the instructions on stackoverflow I managed to get something that seems to work, but it isn't giving me usable values for getRotation:

http://stackoverflow.com/questions/6838397/how-do-i-load-my-own-java-class-in-c-on-android

Here is what I did step by step:
  1. Put Java in my previously pure native activity by sub-classing NativeActivity so that it would call JNI_OnLoad when the app is launched.
  2. Cached the vm passed to JNI_OnLoad
  3. Get the JNIEnv* env for the vm while in JNI_OnLoad
    • nativeJavaVM = vm  (nativeJavaVM declared as JavaVM *nativeJavaVM in global section of Main.c)
  4. Cached the class that I wanted from JNI
    • jclass my_Display = (*env)->FindClass(env, "android/view/Display");
  5. Cashed the method ID for the method I want from the class
    • jmethodID my_getRotation = (*env)->GetMethodID(env, my_Display,"getRotation","()I");
  6. Created a new function in Main.c (I started with the native-activity example code) that should return the rotation value
    • JNIEnv* env;
    • (*nativeJavaVM)->AttachCurrentThread(nativeJavaVM, &env, NULL);
    • int myRotation = (*env)->CallIntMethod(env, jclass_Display, mid_getRotation);
    • (*nativeJavaVM)->DetachCurrentThread(nativeJavaVM);
    • LOGI("Rotation = 0x%08x",myRotation);
As far as I can tell, all of this is working as it should.  The problem is that the value that is returned by getRotation() appears to be garbage.  Instead of the expected hex value 0 to 3 that would tell me what the rotation is, I get something like 0x4052b6d0 with the last four digits different every time I run it.

I've been battling this issue for days so that I can get gravity going the right direction on tablets, but I don't feel like I'm getting anywhere with it.  Would it be too much to ask for a native getRotation() method?

Any suggestions would be welcome!

Mike

David Turner

unread,
Aug 23, 2012, 12:11:07 PM8/23/12
to andro...@googlegroups.com
GetMethodID takes a jcalss as its second parameter.
CallIntMethod takes a jobject as its second parameter

From the code above, it looks like you have mixed up your parameters. Is this a typo?

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/android-ndk/-/p3HHSLIO30UJ.

To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.

mikelong

unread,
Aug 23, 2012, 1:10:46 PM8/23/12
to andro...@googlegroups.com
Hmm.. I think I am putting a jclass in the second field of GetMethodID.  Your second point has exposed some weaknesses in my comprehension of object oriented programming.  The stackoverflow thread is geared toward working with a user defined class, with the comment that calling system methods is trivial (haha).

I guess passing in the uninstantiated class was just wishful thinking.

How do I get a handle to the jobject that I need to pass to CallIntMethod?

Thanks for the help!

Mike

mikelong

unread,
Sep 11, 2012, 11:13:58 PM9/11/12
to andro...@googlegroups.com
I've managed to make the Java getRotation() method return the default orientation for the device via JNI.

It was hard.

I learned a lot.. Especially about how little I know.

I've put the gory details on my blog.


I still don't know how to access anything but static data via JNI, but it gets me past this particular hurdle.

~Mike


On Sunday, November 13, 2011 3:12:45 AM UTC-6, Ratamovic wrote:
Reply all
Reply to author
Forward
0 new messages