注意:你移动手机反映在坐标系上你移动的是坐标系远点(旋转)
1. Accelrator的x,y,z轴的正负向变化:
手机屏幕向上水平放置时: (x,y,z) = (0, 0, -9.81)
当手机顶部抬起时: y减小,且为负值
当手机底部抬起时: y增加,且为正值
当手机右侧抬起时: x减小,且为负值
当手机左侧抬起时: x增加,且为正值
2. Accelrator的z轴的变化:
手机屏幕向上水平放置时,z= -9.81
手机屏幕竖直放置时, z= 0
手机屏幕向下水平放置时,z= 9.81
3. 系统默认屏幕横竖切换
当y变为+-5时, 手机画面切换为竖向
当x变为+-5时, 手机画面切换为横向
4.根据需要你可以设定你想要的旋转阈值
package com.Test.AndroidTest;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
/**
* 以屏幕的左下方为原点(2d编程的时候,是以屏幕左上方为原点的,这个值得注意一下),箭头指向的方向为正。从-10到10,以浮点数为等级单位,想象一下以下情形:
手机屏幕向上(z轴朝天)水平放置的时侯,(x,y,z)的值分别为(0,0,10);
手机屏幕向下(z轴朝地)水平放置的时侯,(x,y,z)的值分别为(0,0,-10);
手机屏幕向左侧放(x轴朝天)的时候,(x,y,z)的值分别为(10,0,0);
手机竖直(y轴朝天)向上的时候,(x,y,z)的值分别为(0,10,0);
其他的如此类推,规律就是:朝天的就是正数,朝地的就是负数。利用x,y,z三个值求三角函数,就可以精确检测手机的运动状态了。
* @author Administrator
*
*/
public class MySensor extends Activity {
/** Tag string for our debug logs */
private static final String TAG = "Sensors";
private SensorManager mSensorManager;
private GraphView mGraphView;
int screenWidth,screenHeight;
private class GraphView extends View implements SensorListener
{
private Bitmap mBitmap;
private Paint mPaint = new Paint();
private Canvas mCanvas = new Canvas();
private Path mPath = new Path();
private RectF mRect = new RectF();
private float mLastValues[] = new float[3 * 2];
private float mOrientationValues[] = new float[3];
private int mColors[] = new int[3 * 2];
private float mLastX;
private float mScale[] = new float[2];
private float mYOffset;
private float mMaxX;
private float mSpeed = 1.0f;
private float mWidth;
private float mHeight;
private int a;
private Paint p = new Paint();
private int movex = 0, movey = 0;
// private int x = 150, y = 200;
private int x = 0, y = 0;
public GraphView(Context context)
{
super(context);
mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
mRect.set(-0.5f, -0.5f, 0.5f, 0.5f);
mPath.arcTo(mRect, 0, 180);
p.setTextSize(20);
movex = 0;
movey = 0;
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
screenWidth=dm.widthPixels;
screenHeight=dm.heightPixels;
Log.d("TAG", "------------screenWidth: "+screenWidth+",height: "+screenHeight);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
Log.d(TAG, "------onSizeChanged--------");
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
mCanvas.setBitmap(mBitmap);
mCanvas.drawColor(0xFFFFFFFF);
mYOffset = h * 0.5f;
mScale[0] = -(h * 0.5f * (1.0f / (SensorManager.STANDARD_GRAVITY * 2)));
mScale[1] = -(h * 0.5f * (1.0f / (SensorManager.MAGNETIC_FIELD_EARTH_MAX)));
mWidth = w;
mHeight = h;
if (mWidth < mHeight)
{
mMaxX = w;
} else
{
mMaxX = w - 50;
}
mLastX = mMaxX;
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas)
{
Log.d(TAG, "----ondraw-------");
synchronized (this)
{
if (mBitmap != null)
{
final Paint paint = mPaint;
final Path path = mPath;
final int outer = 0xFFC0C0C0;
final int inner = 0xFFff7010;
canvas.drawBitmap(mBitmap, 0, 0, null);
int direction=(int)mOrientationValues[0];//方位,繞 Z軸旋轉(0“=方位<360)。 0 =北,90 =東,180 =南,西270 =
String strDriection="0";
switch(direction){
case 90:
strDriection="East";
break;
case 0:
strDriection="North";
break;
case 180:
strDriection="Sourth";
break;
case 270:
strDriection="West";
break;
default :
strDriection="null";
break;
}
canvas.drawText("方位:" + mOrientationValues[0]+", Driection: "+strDriection, 50, 50, p);
canvas.drawText("竖斜度y" + mOrientationValues[1], 50, 100, p);
canvas.drawText("横斜度x:" + mOrientationValues[2], 50, 150, p);
canvas.drawText("測量接觸力x:" + mLastValues[0], 50, 200, p);
canvas.drawText("測量接觸力y:" + mLastValues[1], 50, 250, p);
canvas.drawText("測量接觸力z:" + mLastValues[2], 50, 300, p);
movey = (int) (mOrientationValues[1]);
movex = (int) (mOrientationValues[2]);
x = x + movex;
y = y - movey;
if (x < 0)
x = 0;
if (y < 0)
y = 0;
if (x > canvas.getWidth() - 10)
x = canvas.getWidth() - 10;
if (y > canvas.getHeight() - 80)
y = canvas.getHeight() - 80;
canvas.drawText("屏幕大小:W: "+canvas.getWidth()+",H: "+canvas.getHeight()+",moveY: "+movey+", moveX: "+movex, 20, 350, p);
canvas.drawText("滚球坐标X:" + x, 10, 400, p);
canvas.drawText("滚球坐标Y:" + y, 200, 400, p);
/*圆弧的描画,调用Canvas.drawArc()方法。
第1个参数需要画的矩形new RectF(x, y, x + 10, y + 10)第三四个参数是画出图形宽,高
第2个参数startAngle是指开始的角度。比如,钟表中3点的时候是0度处于水平,6点的时候是90度,从0至360度画出一个小圆
第3个参数sweepAngle是指圆弧的角度。
第4个参数useCenter是指卖描画的图形包不包括圆心(true(包括圆心),false(不包括圆心))、
第5个参数是Paint的实例。*/
canvas.drawArc(new RectF(x, y, x + 10, y + 10), 0, 360,
false, p);//画出小圆
//canvas.drawText("nAndroid123 :"+nAndroid123, 300, 400, p);
/
}
}
}
public void onSensorChanged(int sensor, float[] values)
{
float dx = values[SensorManager.DATA_X];
float dy = values[SensorManager.DATA_Y];
float dz = values[SensorManager.DATA_Z];
setTitle("x="+(int)dx+","+"y="+(int)dy+","+"z="+(int)dz);
synchronized (this)
{
/*所有的值都在度角。
值[0]:方位,繞 Z軸旋轉(0“=方位<360)。 0 =北,90 =東,180 =南,西270 =
值[1]:俯仰,左右旋轉 X軸(-180 <=間距 <= 180),與正面的價值觀時,Z軸移動對 Y軸。
值[2]:橫滾,Y軸的旋轉(-90 <=卷<= 90),與正面的價值觀時,Z軸移動向X軸。
請注意,這個定義的偏航,俯仰和滾動不同於傳統的定義應用於航空,其中X軸是沿著長邊的平面(尾巴鼻子)。*/
if (sensor == SensorManager.SENSOR_ORIENTATION)
{
for (int i = 0; i < 3; i++)
{
mOrientationValues[i] = values[i];
}
}
/*所有的值都在SI單位(米/秒^ 2),測量接觸力。
值[0]:強制適用於該設備的X軸
值[1]:強制適用於該設備在Y軸
值[2]:強制適用於該設備的Z軸
例子:
•當設備被壓在其左側向右時,X為負加速度值(該設備適用於一個反應部隊推向左)
•當設備位於平放在一張桌子,加速度值是- STANDARD_GRAVITY,對應於該部隊的設備適用於表中反應的嚴重性。*/
if (sensor == SensorManager.SENSOR_ACCELEROMETER)
{
for (int i = 0; i < 3; i++)
{
mLastValues[i] = values[i];
}
}
invalidate();
}
}
public void onAccuracyChanged(int sensor, int accuracy)
{
// TODO Auto-generated method stub
}
}
/**
*
* Initialization of the Activity after it is first created. Must at least
*
* call {@link android.app.Activity#setContentView setContentView()} to
*
* describe what is to be displayed in the screen.
*/
@Override
protected void onCreate(Bundle savedInstanceState)
{
// Be sure to call the super class.
super.onCreate(savedInstanceState);
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mGraphView = new GraphView(this);
setContentView(mGraphView);
}
@Override
protected void onResume()
{
super.onResume();
//三个参数分别是监听,感应装置,和灵敏度
mSensorManager.registerListener(mGraphView,
SensorManager.SENSOR_ACCELEROMETER
| SensorManager.SENSOR_MAGNETIC_FIELD
| SensorManager.SENSOR_ORIENTATION,
SensorManager.SENSOR_DELAY_FASTEST);
//灵敏度参数:
//SENSOR_DELAY_FASTEST 最灵敏,快的然你无语
//SENSOR_DELAY_GAME 游戏的时候用这个,不过一般用这个就够了,和上一个很难看出区别
//SENSOR_DELAY_NORMAL 比较慢。
//SENSOR_DELAY_UI 最慢的,几乎就是横和纵的区别
}
@Override
protected void onStop()
{
mSensorManager.unregisterListener(mGraphView);
super.onStop();
}
}