Create a custom View, Compass, extends View. The method update() is called from onSensorChanged() of main activity, with the updated direction.
package com.AndroidDetOrientation;
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 Compass extends View {
private float direction;
public Compass(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public Compass(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public Compass(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(
MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
}
@Override
protected void onDraw(Canvas canvas) {
int w = getMeasuredWidth();
int h = getMeasuredHeight();
int r;
if(w > h){
r = h/2;
}else{
r = w/2;
}
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
paint.setColor(Color.WHITE);
canvas.drawCircle(w/2, h/2, r, paint);
paint.setColor(Color.RED);
canvas.drawLine(
w/2,
h/2,
(float)(w/2 + r * Math.sin(-direction)),
(float)(h/2 - r * Math.cos(-direction)),
paint);
}
public void update(float dir){
direction = dir;
invalidate();
}
}
Modify main activity, AndroidDetOrientationActivity, to update Compass.
package com.AndroidDetOrientation;
import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;
public class AndroidDetOrientationActivity extends Activity
implements SensorEventListener{
SensorManager sensorManager;
private Sensor sensorAccelerometer;
private Sensor sensorMagneticField;
private float[] valuesAccelerometer;
private float[] valuesMagneticField;
private float[] matrixR;
private float[] matrixI;
private float[] matrixValues;
TextView readingAzimuth, readingPitch, readingRoll;
Compass myCompass;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
readingAzimuth = (TextView)findViewById(R.id.azimuth);
readingPitch = (TextView)findViewById(R.id.pitch);
readingRoll = (TextView)findViewById(R.id.roll);
myCompass = (Compass)findViewById(R.id.mycompass);
sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
sensorAccelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorMagneticField = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
valuesAccelerometer = new float[3];
valuesMagneticField = new float[3];
matrixR = new float[9];
matrixI = new float[9];
matrixValues = new float[3];
}
@Override
protected void onResume() {
sensorManager.registerListener(this,
sensorAccelerometer,
SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(this,
sensorMagneticField,
SensorManager.SENSOR_DELAY_NORMAL);
super.onResume();
}
@Override
protected void onPause() {
sensorManager.unregisterListener(this,
sensorAccelerometer);
sensorManager.unregisterListener(this,
sensorMagneticField);
super.onPause();
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
switch(event.sensor.getType()){
case Sensor.TYPE_ACCELEROMETER:
for(int i =0; i < 3; i++){
valuesAccelerometer[i] = event.values[i];
}
break;
case Sensor.TYPE_MAGNETIC_FIELD:
for(int i =0; i < 3; i++){
valuesMagneticField[i] = event.values[i];
}
break;
}
boolean success = SensorManager.getRotationMatrix(
matrixR,
matrixI,
valuesAccelerometer,
valuesMagneticField);
if(success){
SensorManager.getOrientation(matrixR, matrixValues);
double azimuth = Math.toDegrees(matrixValues[0]);
double pitch = Math.toDegrees(matrixValues[1]);
double roll = Math.toDegrees(matrixValues[2]);
readingAzimuth.setText("Azimuth: " + String.valueOf(azimuth));
readingPitch.setText("Pitch: " + String.valueOf(pitch));
readingRoll.setText("Roll: " + String.valueOf(roll));
myCompass.update(matrixValues[0]);
}
}
}
Modify main.xml to add a View of Compass.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<TextView
android:id="@+id/azimuth"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/pitch"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/roll"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<view
class="com.AndroidDetOrientation.Compass"
android:id="@+id/mycompass"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
Great tutorial! All of the raw data readings are very reliable. The compass illustration, however, could use some work.
ReplyDeletei want to ask, how about if I want to link this project (2 class java) with one button, so if I push the button, compass view is launch...how i do that from this project master...???
ReplyDeleteThanks for your help, i very need to do that.
Do you means start another activity when button pressed?
Deletehttp://android-coding.blogspot.com/2011/01/startactivityintent.html
yes i mean, but in this case have two activity, for example this compass project & i give a button, when button pressed the compass isn't show but the program
Delete"force close", how to solve from that case...?
Has any way to work compass on emulator???
ReplyDeleteit doesn't works now... As orientation sensor doesn't works...
ReplyDeleteI've heared that its discarded now(orientation sensor)...
Suggest me solutions for this..
any demo? how can i acheieve direction and angle of my current postion?
regards,
moona