Search code examples
androiddigital-compass

Compass not working on some devices


We recently released an Android port of an iPhone app. The app relies on the digital compass for some features. This has been working well on most devices, but there are a few where the compass is not working. For the description it seems the device is not feeding us any onSensorChanged() messages.

A couple of devices that seem problematic are: HTC Desire on Android 2.2 Motorola Droid on Android 2.2.3

They claim that other apps that make use of the compass work fine.

We start the compass using:

    if ( magnetometer != null && accelerometer != null )
    {
        if ( compassOn )
        {
            sensorManager.registerListener( this, accelerometer, (int) (1000000 / kSensorUpdateFrequencyFast) );
            sensorManager.registerListener( this, magnetometer, (int) (1000000 / kSensorUpdateFrequencyFast) );
        }
        else
        {
            sensorManager.registerListener( this, accelerometer, (int) (1000000 / kSensorUpdateFrequencySlow) );
            sensorManager.registerListener( this, magnetometer, (int) (1000000 / kSensorUpdateFrequencySlow) );
        }
    }

Where the magnetometer and accelerometer are initialized at program startup using:

    sensorManager = (SensorManager) getSystemService( SENSOR_SERVICE );
    accelerometer = sensorManager.getDefaultSensor( Sensor.TYPE_ACCELEROMETER );
    magnetometer = sensorManager.getDefaultSensor( Sensor.TYPE_MAGNETIC_FIELD );

Now the above code indicated that registration doesn't happen if either accelerometer == null or magnetometer == null. I'm pretty sure the magnetometer is not null because if it is we hide the compass feature. So maybe the accelerometer is null on these phones?

The code in my onSensorChanged() is pretty standard and is based on the countless examples you can find on the web.

So does anyone have any thoughts on why the compass code might not be working on those devices?


Solution

  • I did figure this out. Turns out that in 2.2 you can't use sensor rates other than the standard SENSOR_DELAY_UI, SENSOR_DELAY_NORMAL, etc. The documentation claims you can also specify the number of microseconds between notifications, but they are lying.

    Once I used the standard constants it started working on 2.2