You have to implement a "compass". You can do this like this:
Let your activity implement the SensorEventListener and add the necessary fields:
public class CompassActivity extends Activity implements SensorEventListener {
private SensorManager sensorManager;
private Sensor accelerometer;
private Sensor magnetometer;
private float[] lastAccelerometer = new float[3];
private float[] lastMagnetometer = new float[3];
private boolean lastAccelerometerSet = false;
private boolean lastMagnetometerSet = false;
private float[] rotationMatrix = new float[9];
private float[] orientation = new float[3];
private float currentDegree = 0f;
In the onCreate method of the activity get and start the two sensors, the accelerometer and the magnetometer:
// onCreate method stub ...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI);
sensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_UI);
// more onCreate method stub ....
In the method of the SensorEventListener you can now calculate the heading of the phone and calculate the bearing between the current location and a other location:
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor == this.accelerometer) {
System.arraycopy(event.values, 0, this.lastAccelerometer, 0, event.values.length);
this.lastAccelerometerSet = true;
} else if (event.sensor == this.magnetometer) {
System.arraycopy(event.values, 0, this.lastMagnetometer, 0, event.values.length);
this.lastMagnetometerSet = true;
}
if (this.lastAccelerometerSet && this.lastAccelerometerSet) {
SensorManager.getRotationMatrix(this.rotationMatrix,null, this.lastAccelerometer, this.lastMagnetometer);
SensorManager.getOrientation(this.rotationMatrix, this.orientation);
float azimuthInRadiands = this.orientation[0];
// this is now the heading of the phone. If you want
// to rotate a view to north don´t forget that you have
// to rotate by the negative value.
float azimuthInDegrees = (float) Math.toDegrees(azimuthInRadiands);
}
}
But don´t forget that there is much more behind a compass. You have to show the user if the magnetic field sensor is uncalibrated. You have to calculate the difference between the magnetic and the geographic north...
I have created a small compass helper class. The HowTo is in the readme. It will provide you all the information you need to present a compass on the screen:
Compass Assistant on GitHub
It provides you the current heading of the device. Please don´t hesitate to ask me if you have problems.