Andorid 传感器

1. SensorManager:



以屏幕的左下方为原点(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三个值求三角函数,就可以精确检测手机的运动状态了。
下面是修改过的代码,在Milestone上测试成功,在标题栏上显示当前坐标

  
  
  
  
  1. package com.pocketdigi;    
  2. import android.app.Activity;    
  3. import android.os.Bundle;    
  4. import android.hardware.SensorManager;    
  5. import android.hardware.Sensor;    
  6. import android.hardware.SensorEventListener;    
  7. import android.hardware.SensorEvent;    
  8.   
  9.   
  10. public class main extends Activity {    
  11.     private float x, y, z;    
  12.     protected void onCreate(Bundle savedInstanceState) {    
  13.         super.onCreate(savedInstanceState);  
  14.         setContentView(R.layout.main); 
  15.         SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);  
  16.         Sensor sensor = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
  17.         /*TYPE注解 
  18.         intTYPE_ACCELEROMETER 加速度  
  19.                 intTYPE_ALL 所有类型,NexusOne默认为 加速度  
  20.                 intTYPE_GYROSCOPE 回转仪(这个不太懂)  
  21.                 intTYPE_LIGHT 光线感应 
  22.                 intTYPE_MAGNETIC_FIELD 磁场  
  23.                 intTYPE_ORIENTATION 定向(指北针)和角度  
  24.                 intTYPE_PRESSUR 压力计  
  25.                 intTYPE_PROXIMITY 距离?不太懂  
  26.                 intTYPE_TEMPERATURE 温度啦 
  27.          */ 
  28.   
  29.                 SensorEventListener lsn = new SensorEventListener() { 
  30.                     public void onSensorChanged(SensorEvent e) { 
  31.                             x = e.values[SensorManager.DATA_X];    
  32.                             y = e.values[SensorManager.DATA_Y];    
  33.                             z = e.values[SensorManager.DATA_Z]; 
  34.                             setTitle("x="+(int)x+","+"y="+(int)y+","+"z="+(int)z); 
  35.                     } 
  36.   
  37.                     public void onAccuracyChanged(Sensor s, int accuracy) { 
  38.                     } 
  39.                 }; 
  40.                 //注册listener,第三个参数是检测的灵敏度 
  41.                 sensorMgr.registerListener(lsn, sensor, SensorManager.SENSOR_DELAY_GAME); 
  42.                 /* 
  43.                  SENSOR_DELAY_FASTEST 最灵敏,快的然你无语 
  44.                  SENSOR_DELAY_GAME 游戏的时候用这个,不过一般用这个就够了,和上一个很难看出区别 
  45.                  SENSOR_DELAY_NORMAL 比较慢。 
  46.                  SENSOR_DELAY_UI 最慢的,几乎就是横和纵的区别 
  47.                  */ 
  48.     } 
  49.   

2 豆瓣电台里面有一个功能是摇晃换歌,下面谈谈这个功能的实现以及遇到的问题。

 
原理是通过检测android手机带的传感器,检测晃动时的距离和速度,大于一个阀值的话就认为是一个shake动作 首先定义检测的SensorEventListener:

 

  
  
  
  
  1. sensorEventListener = new SensorEventListener() { 
  2.             long lastUpdate,lastShakeTime = 0
  3.             float x,y,last_x = 0,last_y = 0
  4.             static final int SHAKE_THRESHOLD = 1000
  5.  
  6.             public void onAccuracyChanged(Sensor sensor, int accuracy) { 
  7.             } 
  8.  
  9.             public void onSensorChanged(SensorEvent e)  
  10.                 long curTime = System.currentTimeMillis(); 
  11.                 // detect per 100 Millis 
  12.                 if ((curTime - lastUpdate) > 100) { 
  13.                     long diffTime = (curTime - lastUpdate); 
  14.                     lastUpdate = curTime; 
  15.                     //这里做了简化,没有用z的数据 
  16.                     x = e.values[SensorManager.DATA_X]; 
  17.                     y = e.values[SensorManager.DATA_Y]; 
  18.                     //z = Math.abs(values[SensorManager.DATA_Z]); 
  19. float acceChangeRate = 0;// = Math.abs(x+y - last_x - last_y) / diffTime * 1000;   
  20.                     if(last_x != 0) acceChangeRate = Math.abs(x+y - last_x - last_y) / diffTime * 10000
  21.                      //这里设定2个阀值,一个是加速度的,一个是shake的间隔时间的 
  22.                     if (acceChangeRate > SHAKE_THRESHOLD && curTime - lastShakeTime > 2000) { 
  23.  
  24.                         lastShakeTime = curTime; 
  25.                         onShake();//调用shake时的处理函数, 对电台来讲就是换下一首歌 
  26.                     } 
  27.                     last_x = x; 
  28.                     last_y = y; 
  29.                 } 
  30.             } 
  31.         }; 
然后注册就可以了:
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_GAME);


然后再程序退出或是pause的时候调
sensorManager.unregisterListener(sensorEventListener);
不过shake动作的检测是有一个问题的,就是当手机进入睡眠模式(就是按电源键)时,sensorManager是不工作的,也就是检测不到shake动作,对其他传感器也是一样的。可能是为了省电的原因。

 

你可能感兴趣的:(传感器,职场,andorid,休闲,Andorid传感器)