Refer to the last exercise "Detect rotation around X, Y & Z axis, using SensorManager and SensorEventListener", Azimuth can be used to implement compass.

Create a custom view, MyCompassView, extends View. It display the drawing of our compass.
MyCompassView.java
Modify the layout file, main.xml, to add MyCompassView.
Modify the main code, AndroidCompass.java, to handle SensorManager and SensorEventListener.
Modify AndroidManifest.xml to disable the auto-rotate feature, otherwise it will point to wrong direction.
Download the files.
Related Article:
Implement a Simple Horizontal Indicator using SensorManager and SensorEventListener
Create a custom view, MyCompassView, extends View. It display the drawing of our compass.
MyCompassView.java
package com.exercise.AndroidCompass;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class MyCompassView extends View {
private float direction = 0;
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private boolean firstDraw;
public MyCompassView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}
public MyCompassView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}
public MyCompassView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
init();
}
private void init(){
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
paint.setColor(Color.WHITE);
paint.setTextSize(30);
firstDraw = true;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
int cxCompass = getMeasuredWidth()/2;
int cyCompass = getMeasuredHeight()/2;
float radiusCompass;
if(cxCompass > cyCompass){
radiusCompass = (float) (cyCompass * 0.9);
}
else{
radiusCompass = (float) (cxCompass * 0.9);
}
canvas.drawCircle(cxCompass, cyCompass, radiusCompass, paint);
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), paint);
if(!firstDraw){
canvas.drawLine(cxCompass, cyCompass,
(float)(cxCompass + radiusCompass * Math.sin((double)(-direction) * 3.14/180)),
(float)(cyCompass - radiusCompass * Math.cos((double)(-direction) * 3.14/180)),
paint);
canvas.drawText(String.valueOf(direction), cxCompass, cyCompass, paint);
}
}
public void updateDirection(float dir)
{
firstDraw = false;
direction = dir;
invalidate();
}
}Modify the layout file, main.xml, to add MyCompassView.
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
class="com.exercise.AndroidCompass.MyCompassView"
android:id="@+id/mycompassview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
Modify the main code, AndroidCompass.java, to handle SensorManager and SensorEventListener.
package com.exercise.AndroidCompass;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.Toast;
public class AndroidCompass extends Activity {
private static SensorManager mySensorManager;
private boolean sersorrunning;
private MyCompassView myCompassView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myCompassView = (MyCompassView)findViewById(R.id.mycompassview);
mySensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
List mySensors = mySensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
if(mySensors.size() > 0){
mySensorManager.registerListener(mySensorEventListener, mySensors.get(0), SensorManager.SENSOR_DELAY_NORMAL);
sersorrunning = true;
Toast.makeText(this, "Start ORIENTATION Sensor", Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(this, "No ORIENTATION Sensor", Toast.LENGTH_LONG).show();
sersorrunning = false;
finish();
}
}
private SensorEventListener mySensorEventListener = new SensorEventListener(){
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
myCompassView.updateDirection((float)event.values[0]);
}
};
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if(sersorrunning){
mySensorManager.unregisterListener(mySensorEventListener);
}
}
} Modify AndroidManifest.xml to disable the auto-rotate feature, otherwise it will point to wrong direction.
Related Article:
Implement a Simple Horizontal Indicator using SensorManager and SensorEventListener