注意:你移动手机反映在坐标系上你移动的是坐标系远点(旋转)

  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();
 }


}