Xamarin.Essentials: Compass

Pre-release NuGet

The Compass class lets you monitor the device's magnetic north heading.

Using Compass

Add a reference to Xamarin.Essentials in your class:

using Xamarin.Essentials;

The Compass functionality works by calling the Start and Stop methods to listen for changes to the compass. Any changes are sent back through the ReadingChanged event. Here is an example:

public class CompassTest
{
    // Set speed delay for monitoring changes.
    SensorSpeed speed = SensorSpeed.UI;

    public CompassTest()
    {
        // Register for reading changes, be sure to unsubscribe when finished
        Compass.ReadingChanged += Compass_ReadingChanged;
    }

    void Compass_ReadingChanged(object sender, CompassChangedEventArgs e)
    {
        var data = e.Reading;
        Console.WriteLine($"Reading: {data.HeadingMagneticNorth} degrees");
        // Process Heading Magnetic North
    }

    public void ToggleCompass()
    {
        try
        {
            if (Compass.IsMonitoring)
              Compass.Stop();
            else
              Compass.Start(speed);
        }
        catch (FeatureNotSupportedException fnsEx)
        {
            // Feature not supported on device
        }
        catch (Exception ex)
        {
            // Some other exception has occurred
        }
    }
}

Sensor Speed

  • Fastest – Get the sensor data as fast as possible (not guaranteed to return on UI thread).
  • Game – Rate suitable for games (not guaranteed to return on UI thread).
  • Normal – Default rate suitable for screen orientation changes.
  • UI – Rate suitable for general user interface.

If your event handler is not guaranteed to run on the UI thread, and if the event handler needs to access user-interface elements, use the MainThread.BeginInvokeOnMainThread method to run that code on the UI thread.

Platform Implementation Specifics

Android does not provide a API for retrieving the compass heading. We utilize the accelerometer and magnetometer to calculate the magnetic north heading, which is recommended by Google.

In rare instances, you maybe see inconsistent results because the sensors need to be calibrated, which involves moving your device in a figure-8 motion. The best way of doing this is to open Google Maps, tap on the dot for your location, and select Calibrate compass.

Be aware that running multiple sensors from your app at the same time may adjust the sensor speed.

Low Pass Filter

Due to how the Android compass values are updated and calculated there may be a need to smooth out the values. A Low Pass Filter can be applied that averages the sine and cosine values of the angles and can be turned on by setting the ApplyLowPassFilter property on the Compass class:

Compass.ApplyLowPassFilter = true;

This is only applied on the Android platform. More information can be read here.

API