android 重力感应

来源:互联网 发布:ip是网络层协议 编辑:程序博客网 时间:2024/04/27 15:21

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

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

 }

}

原创粉丝点击