Ok, I figured it out. For those trying to do this, you need:
a) title: your title from the hardware compass. It is in degrees east of magnetic north
b) bearing: bearing from your location to your destination. It is in degrees east of truth north.
myLocation.bearingTo(destLocation);
c) declination: the difference between true north and magnetic north
The heading returned from the magnetometer + accelerator is in degrees east of the true (magnetic) north (-180 to +180), so you need to get the difference between north and magnetic north for your location. This difference varies depending on where you are on earth. You can get using the GeomagneticField class.
GeomagneticField geoField; private final LocationListener locationListener = new LocationListener() { public void onLocationChanged(Location location) { geoField = new GeomagneticField( Double.valueOf(location.getLatitude()).floatValue(), Double.valueOf(location.getLongitude()).floatValue(), Double.valueOf(location.getAltitude()).floatValue(), System.currentTimeMillis() ); ... } }
Armed with them, you calculate the angle of the arrow to draw on the map to show where you are, in relation to the destination, and not in the north.
First set your headline with a slope:
heading += geoField.getDeclination();
Secondly, you need to compensate for the direction in which the phone is looking (heading) from the destination, not north. This is the part I'm stuck on. The heading value returned from the compass gives you a value that describes where the magnetic north (in degrees east of true north) is relative to where the phone is pointing. So, for example, if the value is -10, you know that magnetic north is 10 degrees to your left. The bearing gives you the destination angle in degrees east of the true north. Therefore, after you have received compensation for the deviation, you can use the formula below to get the desired result:
heading = myBearing - (myBearing + heading);
Then you will want to convert degrees east of the true north (-180 to +180) to normal degrees (0 to 360):
Math.round(-heading / 360 + 180)