Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
293 views
in Technique[技术] by (71.8m points)

android - Get rotation and display in degrees

I need something very simple, but I could not find a suitable example to learn from. My sole purpose is the following:


As the device is placed flat (on its back) on the desk, it should show 0 (or close to 0) for X and Y axis. When I lift it from the top part (where the speaker is) and the bottom part (where the microphone is) stays put down - it should show me how many degrees is the phone tilted. Mathematically described - show in degrees the angle between the back of the phone and the table, for one of the axises. When I lift the bottom part (and the top part stays put down) then show minus degrees.

The same goes for the other axis - rotating the phone around its long sides.


I tried assembling an app from different examples, using Gyroscope or Accelerometer or Rotation Vector Sensors, but could not come with something working properly.

Can someone give me an example of the onSensorChanged function (as all the work goes on in here) and just tell me which sensor is used, so I know what to register?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are a few examples and tutorials on the web, but be careful. Sensor.TYPE_ORIENTATION became deprecated. You need to calculate rotations by listening to these two sensors Sensor.TYPE_ACCELEROMETER and Sensor.TYPE_MAGNETIC_FIELD.

The tricky part after registering to receive notifications from these sensors, is to figure out how to handle the data received from them. The key part is the following:

public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
       mGravity = event.values;

    if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
       mGeomagnetic = event.values;

    if (mGravity != null && mGeomagnetic != null) {
       float R[] = new float[9];
       float I[] = new float[9];

       boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
       if (success) {
          float orientation[] = new float[3];
          SensorManager.getOrientation(R, orientation);
          azimuth = orientation[0]; // orientation contains: azimuth, pitch and roll
          pitch = orientation[1];
          roll = orientation[2];
       }
    }
}

This is how you should be calculating the azimuth, pitch, roll values of your device in the onSensorChanged(SensorEvent event) callback. Keep in mind that "All three angles above are in radians and positive in the counter-clockwise direction". You can simply convert them to degrees with Math.toDegrees()

As Louis CAD pointed out in the comments, it is a good idea to move the initialization of the I, R and orientation arrays out of the onSensorChanged callback, since it is called frequently. Creating and then leaving them behind for the GC is bad for your apps performance. I left it there for the sake of simplicity.

Based on how your device is rotated you might need to remap the coordinates to get the result you want. You can read more about remapCoordinateSystem and also about getRotationMatrix and getOrientation in the android documentation

Example code: http://www.codingforandroid.com/2011/01/using-orientation-sensors-simple.html


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...