重力感应主要是依靠手机的加速度传感器(accelerometer)来实现        在Android的开发中一共有八种传感器但是不一定每一款真机都支持这些传感器。因为很多功能用户根本不care的所以可能开发商会把某些功能屏蔽掉。还是得根据真机的实际情况来做开发,今天我们主要来讨论加速度传感器的具体实现方式。
  传感器名称如下:
  加速度传感器(accelerometer)
  陀螺仪传感器(gyroscope)
  环境光照传感器(light)
  磁力传感器(magnetic field)
  方向传感器(orientation)
  压力传感器(pressure)
  距离传感器(proximity)
  温度传感器(temperature)
  1. SensorMannager传感器管理对象手机中的所有传感器都须要通过SensorMannager来访问,调用getSystemService(SENSOR_SERVICE)方法就可以拿到当前手机的传感器管理对象。
Java代码
    - SensorManager mSensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);  
  2. 实现SensorEventListener接口
  说道SensorEventListener接口就不得不说SensorListener接口。在Android1.5一下是通过实现SensorListener接口来捕获 手机传感器状态,但是在1.5以上如果实现这个接口系统会提示你这行代码已经过期。今天我们不讨论SensorListener因为它已经是过时的东西了。主要讨论一下SensorEventListener接口。我们须要实现SensorEventListener这个接口 onSensorChanged(SensorEvent event)方法来捕获手机传感器的状态,拿到手机 X轴Y轴Z轴三个方向的重力分量,有了这三个方向的数据重力感应的原理我们就已经学会了,简单吧 哇咔咔~~
Java代码
    - public void onSensorChanged(SensorEvent e) {  
-    float x = e.values[SensorManager.DATA_X];  
-    float y = e.values[SensorManager.DATA_Y];  
-    float z = e.values[SensorManager.DATA_Z];  
- }  
  如图所示:上例代码中 float x y z 3个方向的取值范围是在 -10 到 10 之间,我向同学们说明一下 X轴 Y轴 Z轴 重力分量的含义。 这里须要注意的是坐标原点 向天空为正数 向地面为负数 刚好与编程时坐标是相反的。
  手机屏幕向左侧方当X轴就朝向天空,垂直放置 这时候 Y 轴 与 Z轴没有重力分量,因为X轴朝向天空所以它的重力分量则最大 。这时候X轴 Y轴 Z轴的重力分量的值分别为(10,0,0)
  手机屏幕向右侧方当X轴就朝向地面,垂直放置 这时候 Y 轴 与 Z轴没有重力分量,因为X轴朝向地面所以它的重力分量则最小 。这时候X轴 Y轴 Z轴的重力分量的值分别为(-10,0,0)
  手机屏幕垂直竖立放置方当Y轴就朝向天空,垂直放置 这时候 X 轴 与 Z轴没有重力分量,因为Y轴朝向天空所以它的重力分量则最大 。这时候X轴 Y轴 Z轴的重力分量的值分别为(0,10,0)
  手机屏幕垂直竖立放置方当Y轴就朝向地面,垂直放置 这时候 X 轴 与 Z轴没有重力分量,因为Y轴朝向地面所以它的重力分量则最小 。这时候X轴 Y轴 Z轴的重力分量的值分别为(0,-10,0)
  手机屏幕向上当Z轴就朝向天空,水平放置 这时候 X 轴与Y轴没有重力分量,因为Z轴朝向天空所以它的重力分量则最大 。这时候X轴 Y轴 Z轴的重力分量的值分别为(0,0,10)
  手机屏幕向上当Z轴就朝向地面,水平放置 这时候 X 轴与Y轴没有重力分量,因为Z轴朝向地面所以它的重力分量则最小 。这时候X轴 Y轴 Z轴的重力分量的值分别为(0,0,-10)
  因为这张图片是在模拟器上截得,所以没有重力感应它的三个方向的的重力分量都为0。

  3. 注册SensorEventListener
  使用SensorMannager调用getDefaultSensor(Sensor.TYPE_ACCELEROMETER)方法拿到加速重力感应的Sensor对象。因为本章我们讨论重力加速度传感器所以参数为Sensor.TYPE_ACCELEROMETER,如果须要拿到其它的传感器须要传入对应的名称。使用SensorMannager调用registerListener()方法来注册,第三个参数是检测的灵敏精确度根据不同的需求来选择精准度,游戏开发建议使用  SensorManager.SENSOR_DELAY_GAME。
Java代码
    - mSensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);  
- mSensor = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);  
-   
-   
-   
-   
-   
- mSensorMgr.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME);   
  重力感应简单速度计算的方式。 每次摇晃手机计算出 X轴 Y轴 Z轴的重力分量可以将它们记录下来 然后每次摇晃的重力分量和之前的重力分量可以做一个对比 利用差值和时间就可以计算出他们的移动速度。(下面这段代码是我之前的博文中摘录过来的,因为那篇写的不是很好所以在这一篇中我详细总结一下)
Java代码
    - private SensorManager sensorMgr;  
- Sensor sensor = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);       
-   
-    
-  float bx = 0;  
-  float by = 0;  
-  float bz = 0;  
-  long btime = 0;  
-  sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);  
-     SensorEventListener lsn = new SensorEventListener() {  
-         public void onSensorChanged(SensorEvent e) {  
-            float x = e.values[SensorManager.DATA_X];  
-            float y = e.values[SensorManager.DATA_Y];  
-            float z = e.values[SensorManager.DATA_Z];  
-              
-              
-              
-            float speadX = (x - bx) / (System.currentTimeMillis() - btime);  
-              
-            float speadY = (y - by) / (System.currentTimeMillis() - btime);  
-              
-            float speadZ = (z - bz) / (System.currentTimeMillis() - btime);  
-              
-              
-              
-   
-            bx = x;  
-            by = y;  
-            bz = z;    
-   
-            btime = System.currentTimeMillis();    
-   
-         }       
-   
-         public void onAccuracyChanged(Sensor s, int accuracy) {  
-         }  
-     };  
-       
-     sensorMgr.registerListener(lsn, sensor, SensorManager.SENSOR_DELAY_GAME);  

  下面给出这个DEMO小球重力感应的完整代码
Java代码
    - import android.app.Activity;  
- import android.content.Context;  
- import android.content.pm.ActivityInfo;  
- import android.graphics.Bitmap;  
- import android.graphics.BitmapFactory;  
- import android.graphics.Canvas;  
- import android.graphics.Color;  
- import android.graphics.Paint;  
- import android.hardware.Sensor;  
- import android.hardware.SensorEvent;  
- import android.hardware.SensorEventListener;  
- import android.hardware.SensorManager;  
- import android.os.Bundle;  
- import android.view.SurfaceHolder;  
- import android.view.SurfaceView;  
- import android.view.Window;  
- import android.view.WindowManager;  
- import android.view.SurfaceHolder.Callback;  
-    
- public class SurfaceViewAcitvity extends Activity {  
-    
-     MyView mAnimView = null;  
-    
-     @Override  
-     public void onCreate(Bundle savedInstanceState) {  
-     super.onCreate(savedInstanceState);  
-       
-     requestWindowFeature(Window.FEATURE_NO_TITLE);  
-     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
-         WindowManager.LayoutParams.FLAG_FULLSCREEN);  
-       
-     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);  
-    
-       
-     mAnimView = new MyView(this);  
-     setContentView(mAnimView);  
-     }  
-    
-     public class MyView extends SurfaceView implements Callback,Runnable ,SensorEventListener{  
-    
-        
-     public static final int TIME_IN_FRAME = 50;   
-    
-       
-     Paint mPaint = null;  
-     Paint mTextPaint = null;  
-     SurfaceHolder mSurfaceHolder = null;  
-    
-       
-     boolean mRunning = false;  
-    
-       
-     Canvas mCanvas = null;  
-    
-       
-     boolean mIsRunning = false;  
-    
-       
-     private SensorManager mSensorMgr = null;  
-     Sensor mSensor = null;      
-    
-       
-     int mScreenWidth = 0;  
-     int mScreenHeight = 0;  
-    
-       
-     private int mScreenBallWidth = 0;  
-     private int mScreenBallHeight = 0;  
-    
-       
-     private Bitmap mbitmapBg;  
-    
-       
-     private Bitmap mbitmapBall;  
-    
-       
-     private float mPosX = 200;  
-     private float mPosY = 0;  
-    
-       
-     private float mGX = 0;  
-     private float mGY = 0;  
-     private float mGZ = 0;  
-    
-     public MyView(Context context) {  
-         super(context);  
-           
-         this.setFocusable(true);  
-           
-         this.setFocusableInTouchMode(true);  
-           
-         mSurfaceHolder = this.getHolder();  
-           
-         mSurfaceHolder.addCallback(this);  
-           
-         mCanvas = new Canvas();  
-           
-         mPaint = new Paint();  
-         mPaint.setColor(Color.WHITE);  
-           
-         mbitmapBall = BitmapFactory.decodeResource(this.getResources(), R.drawable.ball);  
-           
-         mbitmapBg = BitmapFactory.decodeResource(this.getResources(), R.drawable.bg);  
-    
-           
-         mSensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);  
-         mSensor = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);  
-           
-               
-               
-               
-               
-         mSensorMgr.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME);  
-     }  
-    
-     private void Draw() {  
-    
-           
-         mCanvas.drawBitmap(mbitmapBg,0,0, mPaint);  
-           
-         mCanvas.drawBitmap(mbitmapBall, mPosX,mPosY, mPaint);  
-           
-         mCanvas.drawText("X轴重力值 :" + mGX, 0, 20, mPaint);  
-         mCanvas.drawText("Y轴重力值 :" + mGY, 0, 40, mPaint);  
-         mCanvas.drawText("Z轴重力值 :" + mGZ, 0, 60, mPaint);  
-     }  
-    
-     @Override  
-     public void surfaceChanged(SurfaceHolder holder, int format, int width,  
-         int height) {  
-    
-     }  
-    
-     @Override  
-     public void surfaceCreated(SurfaceHolder holder) {  
-           
-         mIsRunning = true;  
-         new Thread(this).start();  
-           
-         mScreenWidth = this.getWidth();  
-         mScreenHeight = this.getHeight();  
-    
-           
-         mScreenBallWidth = mScreenWidth - mbitmapBall.getWidth();  
-         mScreenBallHeight = mScreenHeight - mbitmapBall.getHeight();  
-     }  
-    
-     @Override  
-     public void surfaceDestroyed(SurfaceHolder holder) {  
-         mIsRunning = false;  
-     }  
-    
-     @Override  
-     public void run() {  
-         while (mIsRunning) {  
-    
-           
-         long startTime = System.currentTimeMillis();  
-    
-           
-         synchronized (mSurfaceHolder) {  
-               
-             mCanvas = mSurfaceHolder.lockCanvas();  
-             Draw();  
-               
-             mSurfaceHolder.unlockCanvasAndPost(mCanvas);  
-         }  
-    
-           
-         long endTime = System.currentTimeMillis();  
-    
-           
-         int diffTime = (int) (endTime - startTime);  
-    
-           
-         while (diffTime <= TIME_IN_FRAME) {  
-             diffTime = (int) (System.currentTimeMillis() - startTime);  
-               
-             Thread.yield();  
-         }  
-    
-         }  
-    
-     }  
-    
-     @Override  
-     public void onAccuracyChanged(Sensor arg0, int arg1) {  
-           
-    
-     }  
-    
-     @Override  
-     public void onSensorChanged(SensorEvent event) {  
-         mGX = event.values[SensorManager.DATA_X];  
-         mGY= event.values[SensorManager.DATA_Y];  
-         mGZ = event.values[SensorManager.DATA_Z];  
-    
-           
-         mPosX -= mGX * 2;  
-         mPosY += mGY * 2;  
-    
-           
-         if (mPosX < 0) {  
-         mPosX = 0;  
-         } else if (mPosX > mScreenBallWidth) {  
-         mPosX = mScreenBallWidth;  
-         }  
-         if (mPosY < 0) {  
-         mPosY = 0;  
-         } else if (mPosY > mScreenBallHeight) {  
-         mPosY = mScreenBallHeight;  
-         }  
-     }  
-     }  
- }  
  源码下载地址:http://vdisk.weibo.com/s/aajXn