//package apps.compass;
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.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class CompassView extends View {
private float mGraduationRotateAngle = 0;
private float mPointerRotateAngle = 0;
private Drawable mGraduationDrawable = null;
private Drawable mPointerDrawable = null;
private float mGraduationDrawableRadius = 0;
private float mPointerDrawableRadius = 0;
private float mCanvasCenterX = 0;
private float mCanvasCenterY =0;
private float mPreTouchX = 0;
private float mPreTouchY = 0;
public CompassView(Context context) {
super(context);
Resources res = context.getResources();
// mGraduationDrawable = res.getDrawable();
mGraduationDrawable.setBounds(0, 0, 300, 300);
// mPointerDrawable = res.getDrawable();
mPointerDrawable.setBounds(0, 0, 250, 250);
mGraduationDrawableRadius = 300 / 2;
mPointerDrawableRadius = 250 / 2;
}
public void setPointerRotateAngle(float angle) {
if (angle - mPointerRotateAngle > 2 ) {
while (angle - mPointerRotateAngle > 0.2) {
mPointerRotateAngle += 0.2;
this.invalidate();
}
}
else if (angle - mPointerRotateAngle < -2) {
while (mPointerRotateAngle - angle > 0.2) {
mPointerRotateAngle -= 0.2;
this.invalidate();
}
}
}
public void setGraduationRotateAngle(float angle) {
mGraduationRotateAngle = angle;
}
public boolean onTouchEvent(MotionEvent event) {
boolean hasRotation = false;
boolean isClockwise = true;
float dx = event.getX() - mPreTouchX;
float dy = event.getY() - mPreTouchY;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
if (mPreTouchX > mCanvasCenterX && mPreTouchX < mCanvasCenterX + mGraduationDrawableRadius) {
if (mPreTouchY > mCanvasCenterY && mPreTouchY < mCanvasCenterY + mGraduationDrawableRadius) {
if (dx > 0 && dy < 0) {isClockwise = true; hasRotation = true;}
else if (dx < 0 && dy > 0) {isClockwise = false; hasRotation = true;}
else {hasRotation = false;}
}
else if (mPreTouchY > mCanvasCenterY - mGraduationDrawableRadius && mPreTouchY < mCanvasCenterY){
if (dx > 0 && dy > 0) {isClockwise = false; hasRotation = true;}
else if (dx < 0 && dy < 0) {isClockwise = true; hasRotation = true;}
else {hasRotation = false;}
}
}
else if (mPreTouchX > mCanvasCenterX - mGraduationDrawableRadius && mPreTouchX < mCanvasCenterX){
if (mPreTouchY > mCanvasCenterY && mPreTouchY < mCanvasCenterY + mGraduationDrawableRadius) {
if (dx > 0 && dy > 0) {isClockwise = true; hasRotation = true;}
else if (dx < 0 && dy < 0) {isClockwise = false; hasRotation = true;}
else {hasRotation = false;}
}
else if (mPreTouchY > mCanvasCenterY - mGraduationDrawableRadius && mPreTouchY < mCanvasCenterY) {
if (dx > 0 && dy < 0) {isClockwise = false; hasRotation = true;}
else if (dx < 0 && dy > 0) {isClockwise = true; hasRotation = true;}
else {hasRotation = false;}
}
}
break;
}
if (hasRotation) {
float touchXToCenterX = mPreTouchX - mCanvasCenterX;
float touchYToCenterY = mPreTouchY - mCanvasCenterY;
float touchRadius = (float)Math.sqrt(touchXToCenterX * touchXToCenterX + touchYToCenterY * touchYToCenterY);
float touchPathLen = (float) Math.sqrt(dx * dx + dy * dy);
float rotateDegree = (float) Math.toDegrees(touchPathLen / touchRadius);
Log.d("On Touch", "angle: "+rotateDegree);
if (isClockwise)
this.setGraduationRotateAngle(mGraduationRotateAngle + rotateDegree);
else
this.setGraduationRotateAngle(mGraduationRotateAngle - rotateDegree);
this.invalidate();
}
mPreTouchX = event.getX();
mPreTouchY = event.getY();
return true;
}
protected void onDraw(Canvas canvas) {
int w = canvas.getWidth();
int h = canvas.getHeight();
mCanvasCenterX = w / 2;
mCanvasCenterY = h / 2;
canvas.save();
canvas.translate(mCanvasCenterX, mCanvasCenterY);
canvas.rotate(-mGraduationRotateAngle);
canvas.translate(-mGraduationDrawableRadius, -mGraduationDrawableRadius);
mGraduationDrawable.draw(canvas);
canvas.restore();
canvas.translate(mCanvasCenterX, mCanvasCenterY);
canvas.rotate(-mPointerRotateAngle);
canvas.translate(-mPointerDrawableRadius, -mPointerDrawableRadius);
mPointerDrawable.draw(canvas);
}
}
class Compass extends Activity {
private SensorManager mSensorManager = null;
private CompassView mView = null;
private final SensorEventListener mSensorEventListener = new SensorEventListener() {
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
if (mView != null) {
mView.setPointerRotateAngle(event.values[0]);
}
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mView = new CompassView(this);
setContentView(mView);
}
public void onResume() {
super.onResume();
List sensorList = mSensorManager
.getSensorList(Sensor.TYPE_ORIENTATION);
if (!sensorList.isEmpty()) {
Sensor sensor = (Sensor) sensorList.get(0);
if (sensor != null)
mSensorManager.registerListener(mSensorEventListener, sensor,
SensorManager.SENSOR_DELAY_GAME);
}
}
public void onStop() {
mSensorManager.unregisterListener(mSensorEventListener);
super.onStop();
}
}