[FIXED] Android Compass doesn't point North and keeps changing

Issue

So, I have been working on fixing this bug in my Android Compass for 2 days now.
Basically I am trying to build a Qibla Compass using Xamarin.Android . The First step should be to build a Compass that points to North.

I have translated the JAVA code from this tutorial for my Compass to show proper North .

I am simply rotating my Relative Layout which contains my Compass Image whenever Sensor reading Changes.

I have tried tweaking code by intuition but this simple Compass doesn’t love staying at one place. I am just trying to hold the North of my Compass Image aligned to the Magnetic north.

However my compass never shows the correct North also the North keeps changing.

To check my device Compass indeed works I tested an App from Playstore and it ran pretty smooth.

My Activity :

public class QiblaDirectionActivity : Activity, ISensorEventListener
//all the right inherits done

My design code Snippet :

            <RelativeLayout
            android:layout_width="wrap_content"
            android:id="@+id/qiblaRL"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/qiblaCompass"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:scaleType="fitCenter"
                android:layout_centerInParent="true"
                android:src="@drawable/compass" />
            <ImageView
                android:id="@+id/qiblaArrow"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:scaleType="fitCenter"
                android:layout_centerInParent="true"
                android:src="@drawable/needle" />
        </RelativeLayout>

My BackEnd :

 float currentCompassDegree = 0f;
 public void OnSensorChanged(SensorEvent e)
    {
       //I have checked the accuracy its high
        RotateAnimation ra = new RotateAnimation(currentCompassDegree,-e.Values[0], Dimension.RelativeToSelf, 0.5f, Dimension.RelativeToSelf, 0.5f);
        ra.Duration = 120;
        ra.FillAfter = true;
        qiblaRL.StartAnimation(ra);

        currentCompassDegree = -e.Values[0];

    }

I register my listener here :

protected override void OnResume()
    {
        base.OnResume();
        if (_sensorManager != null)
        {

            var mF = _sensorManager.GetDefaultSensor(SensorType.MagneticField);
            _sensorManager.RegisterListener(this, mF, SensorDelay.Ui);
            qiblaAdvice.Text= "(Align Device Properly)";
        }
        else
        {
            qiblaAdvice.Text = "(Device doesn't support Compass)";
        }



    }

And I unregister it here :

   protected override void OnPause()
    {
        base.OnPause();

        if (_sensorManager != null)
        {
            _sensorManager.UnregisterListener(this);
        }
    }

Solution

Magnetic field sensors will contain a lot of noise

You will need to sample and smooth it.

Here is an answer where someone converted the high pass filter sample from Apple/iOS to Android for Accelerometer readings, but I used it for other smoothing purposes and you can strip it from three axis’ to one like I have done:

For “true” North vs. a magnetic North

You can look at the offset received from your current declination and adjust the reading you are getting from your sensor.

There are numerous question/answers regarding this, here is just one:

The declination of the horizontal component of the magnetic field from true north, in degrees (i.e. positive means the magnetic field is rotated east that much from true north).

Interesting answer on compensating for Tilt and Pitch of your phone:

Android Compass that can Compensate for Tilt and Pitch

Answered By – SushiHangover

Answer Checked By – Dawn Plyler (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published