Announcing Stack Overflow Documentation



Sign up and start helping → Learn more about Documentation →

I am trying to program a compass with Android using the accelorometer and the magnetic field sensor, now I am wondering how to get the correct angle for my compass.

I read in the values of the accelerometer and of the magnetic field sensor in "accele", and "magne" respectively. To get the angle, I perform the following:

float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, accele, magne);
        if(success) {
            float orientation[] = new float[3];
            SensorManager.getOrientation(R, orientation);
            azimuth = orientation[0]; // contains azimuth, pitch, roll

Later on, I use a rotation matrix to put my needle:

rotation.setRotate(azimuth, compass.getWidth() / 2, compass.getHeight() / 2);
canvas.drawBitmap(needle, rotation, null);

Now, the documentation of getOrientation says, that orientation[0] should be the rotation around the z-axis. The documentation for TYPE_ORIENTATION states that "Azimuth, angle between the magnetic north direction and the y-axis, around the z-axis (0 to 359). 0=North, 90=East, 180=South, 270=West".

My azimuth however is not between 0 and 359, but rather around -2 to 2. What exactly is the azimuth from getOrientation and how can I convert it to an angle?

share|improve this question
up vote 15 down vote accepted

Use the following to convert from the given azimuth in radians (-PI, +PI) to degrees (0, 360)

float azimuthInRadians = orientation[0];
float azimuthInDegress = (float)Math.toDegrees(azimuthInRadians);
if (azimuthInDegress < 0.0f) {
    azimuthInDegress += 360.0f;

variable names used for convenience ;-)

share|improve this answer
thanks :) What exactly is the last if statement for? – user1809923 Nov 8 '12 at 17:49
the Math.toDegrees() will give you an angle between -180 and 180 from a -PI and +PI radians angle. This just put everything on the positive direction. – rgrocha Nov 9 '12 at 10:28
This is the right answer. – Uriel Frankel Nov 10 '12 at 10:36
Hi! Yes, this should actually work. Thanks! However -180 and 180 are interpreted as the same from Matrix.setRotate(), so the if clause is not necessary – user1809923 Nov 10 '12 at 12:46

A code snippet could be got from https://github.com/iutinvg/compass

It does not use deprecated stuffs, applies low-pass filter.

share|improve this answer
what are the criteria to decide final float alpha = 0.97f; You have used 0.97 as filter constant, google has used 0.8. – Null n Void Feb 24 at 7:59
It will affect the velocity of the arrow rotation. So the choice is based on visual sense: more smooth movement. – iutinvg Feb 25 at 6:12

I found this in the google's ApiDemos:

 * Copyright (C) 2007 The Android Open Source Project
 * You may obtain a copy of the License at
 *      http://www.apache.org/licenses/LICENSE-2.0
 * See the License for the specific language governing permissions and
 * limitations under the License.

package com.example.android.apis.graphics;

import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Config;
import android.util.Log;
import android.view.View;

public class Compass extends GraphicsActivity {

    private static final String TAG = "Compass";

    private SensorManager mSensorManager;
    private SampleView mView;
    private float[] mValues;

    private final SensorListener mListener = new SensorListener() {

            if (Config.LOGD) Log.d(TAG, "sensorChanged (" + values[0] + ", " + values[1] + ", " + values[2] + ")");
            mValues = values;
            if (mView != null) {

        public void onAccuracyChanged(int sensor, int accuracy) {
            // TODO Auto-generated method stub


    protected void onCreate(Bundle icicle) {
        mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
        mView = new SampleView(this);

    protected void onResume()
        if (Config.LOGD) Log.d(TAG, "onResume");

    protected void onStop()
        if (Config.LOGD) Log.d(TAG, "onStop");

    private class SampleView extends View {
        private Paint   mPaint = new Paint();
        private Path    mPath = new Path();
        private boolean mAnimate;
        private long    mNextTime;

        public SampleView(Context context) {

            // Construct a wedge-shaped path
            mPath.moveTo(0, -50);
            mPath.lineTo(-20, 60);
            mPath.lineTo(0, 50);
            mPath.lineTo(20, 60);

        @Override protected void onDraw(Canvas canvas) {
            Paint paint = mPaint;



            int w = canvas.getWidth();
            int h = canvas.getHeight();
            int cx = w / 2;
            int cy = h / 2;

            canvas.translate(cx, cy);
            if (mValues != null) {            
            canvas.drawPath(mPath, mPaint);

        protected void onAttachedToWindow() {
            mAnimate = true;

        protected void onDetachedFromWindow() {
            mAnimate = false;

As you can see you do get the degrees between 0 to 360

share|improve this answer
that would be great, if you explained :) – user1809923 Nov 8 '12 at 17:11
Ok, I will edit my answer. – Uriel Frankel Nov 8 '12 at 17:12
hi, that's an interesting approach, however I think this might not be very accurate, since I just estimated the -2 to 2. – user1809923 Nov 8 '12 at 17:49
I edited it again. – Uriel Frankel Nov 8 '12 at 22:41
I am still a bit confused. First, I still think we need to use orientation[0], since then we rotate around Z, while Y is pointing North and X roughly West. About the conversion: The usual conversion from radians to degrees is: degrees = (radians/pi)*180. However here the radians is assumed to be between 0 and 2pi, I believe. Since I think my radians rangens between -pi and pi, I would get degrees = (radians/pi)*180 + 180 if I transform radians accordignly, wouldn't I? – user1809923 Nov 9 '12 at 8:13

Your Answer


