android 重力感应的使用

作者:GrayD


重力感应主要是依靠手机的加速度传感器(accelerometer)来实现


在Android的开发中一共有八种传感器但是不一定每一款真机都支持这些传感器。因为很多功能用户根本不care的所以可能开发商会把某些功能屏蔽掉。还是得根据真机的实际情况来做开发,下面主要讨论加速度传感器的具体实现方式,传感器名称如下:

加速度传感器(accelerometer)

陀螺仪传感器(gyroscope)

环境光照传感器(light)

磁力传感器(magnetic field)

方向传感器(orientation)

压力传感器(pressure)

距离传感器(proximity)

温度传感器(temperature)


1.SensorMannager传感器管理对象

手机中的所有传感器都须要通过SensorMannager来访问,调用getSystemService (SENSOR_SERVICE)方法就可以拿到当前手机的传感器管理对象。


2.实现SensorEventListener接口

我们需要实现SensorEventListener接口onSensorChanged(SensorEventevent)方法来捕获手机传感器的状态,拿到手机 X轴Y轴Z轴三个方向的重力分量,有了这三个方向的数据重力感应的原理我们就已经学会了。

  1. public void onSensorChanged(SensorEvent e) {        
  2.    float x = e.values[SensorManager.DATA_X];           
  3.    float y = e.values[SensorManager.DATA_Y];           
  4.    float z = e.values[SensorManager.DATA_Z];         
  5. }      

如上述代码所示:float x y z 3个方向的取值范围是在-10到10之间。下面解释一下X轴 Y轴 Z轴 重力分量的含义(这里须要注意的是坐标原点:向天空为正数,向地面为负数,刚好与编程时坐标是相反的):


(1)手机屏幕向左侧方,X轴就朝向天空,垂直放置,这时候 Y 轴与Z轴没有重力分量,因为X轴朝向天空所以它的重力分量则最大。这时候X轴、Y轴、Z轴的重力分量的值分别为(10,0,0);


(2)手机屏幕向右侧方,X轴就朝向地面,垂直放置,这时候 Y 轴与 Z轴没有重力分量,因为X轴朝向地面所以它的重力分量则最小。这时候X轴、Y轴、Z轴的重力分量的值分别为(-10,0,0);


(3)手机屏幕垂直竖立放置,Y轴就朝向天空,垂直放置,这时候X 轴与Z轴没有重力分量,因为Y轴朝向天空所以它的重力分量则最大。这时候X轴、Y轴、Z轴的重力分量的值分别为(0,10,0);


(4)手机屏幕垂直竖立放置,Y轴就朝向地面,垂直放置,这时候X 轴与Z轴没有重力分量,因为Y轴朝向地面所以它的重力分量则最小 。这时候X轴、Y轴、Z轴的重力分量的值分别为(0,-10,0);


(5)手机屏幕向上,Z轴就朝向天空,水平放置,这时候 X 轴与Y轴没有重力分量,因为Z轴朝向天空所以它的重力分量则最大。这时候X轴、Y轴、Z轴的重力分量的值分别为(0,0,10);


(6)手机屏幕向上,Z轴就朝向地面,水平放置,这时候 X 轴与Y轴没有重力分量,因为Z轴朝向地面所以它的重力分量则最小。这时候X轴、Y轴、Z轴的重力分量的值分别为(0,0,-10)。


3.注册SensorEventListener

使用SensorMannager调用getDefaultSensor(Sensor.TYPE_ACCELEROMETER)方法拿到加速重力感应的Sensor对象。因为我讨论的是重力加速度传感器所以参数为Sensor.TYPE_ACCELEROMETER,如果需要拿到其它的传感器需要传入对应的名称。使用SensorMannager调用registerListener()方法来注册,第三个参数是检测的灵敏精确度,根据不同的需求来选择精准度,游戏开发建议使用  SensorManagerSENSOR_DELAY_ GAME。


4 .重力感应简单速度计算的方式。

每次摇晃手机计算出 X轴 Y轴 Z轴的重力分量可以将它们记录下来 然后每次摇晃的重力分量和之前的重力分量可以做一个对比,利用差值和时间就可以计算出他们的移动速度。

  重力感应装置包括感应器、处理器和控制器三个部分。感应器负责侦测存储器的状态,计算存储器的重力加速度值;处理器则对加速度值是否超出安全范围进行判断;而控制器则负责控制将磁头锁定或者释放出安全停泊区。一旦感应器侦测并经处理器判断当前的重力加速度超过安全值之后,控制器就会通过硬件控制磁头停止读写工作,并快速归位,锁定在专有的磁头停泊区。这一系列动作会在200毫秒内完成。当感应装置探测到加速度值恢复到正常值范围之后,产品才会恢复工作。

  Android多媒体框架的代码在以下目录中:external/opencore/.这个目录是Android多媒体框架的根目录,其中包含的子目录如下所示:

* android:这里面是一个上层的库,它基于PVPlayer和PVAuthor的SDK实现了一个为Android使用的Player和Author

* baselibs:包含数据结构和线程安全等内容的底层库

  * codecs_v2:这是一个内容较多的库,主要包含编解码的实现,以及一个OpenMAX的实现

  * engines:包含PVPlayer和PVAuthor引擎的实现

  *extern_libs_v2:包含了khronos的OpenMAX的头文件

  *fileformats:文件格式的据具体解析(parser)类

  * nodes:编解码和文件解析的各个node类

  * oscl:操作系统兼容库

  * pvmi: 输入输出控制的抽象接口

  * protocols:主要是与网络相关的RTSP、RTP、HTTP等协议的相关内容

  * pvcommon:pvcommon库文件的Android.mk文件,没有源文件

  *pvplayer:pvplayer库文件的Android.mk文件,没有源文件

* pvauthor:pvauthor库文件的Android.mk文件,没有源文件

* tools_v2:编译工具以及一些可注册的模块

以下是部分测试代码:


private SensorManager sensorMgr;    
    Sensor sensor = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);     
     //保存上一次 x y z 的坐标  
     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];    
               //计算出 X Y Z的数值下面可以根据这个数值来计算摇晃的速度了   
               //速度 = 路程/时间  
               //X轴的速度  
               float speadX = (x - bx) / (System.currentTimeMillis() - btime);   
               //y轴的速度  
               float speadY = (y - by) / (System.currentTimeMillis() - btime);   
               //z轴的速度  
               float speadZ = (z - bz) / (System.currentTimeMillis() - btime);   
               //这样简单的速度就可以计算出来,如果你想计算加速度也可以,在运动学里,加速度a与速度,  
               //位移都有关系:Vt=V0+at,S=V0*t+1/2at^2, S=(Vt^2-V0^2)/(2a),根据这些信息也可以求解a   
               bx = x;  
               by = y;  
               bz = z;  
               btime = System.currentTimeMillis();  
            }    
            public void onAccuracyChanged(Sensor s, int accuracy) {     
            }     
        };     
        // 注册listener,第三个参数是检测的精确度  
        sensorMgr.registerListener(lsn, sensor, SensorManager.SENSOR_DELAY_GAME);  


你可能感兴趣的:(android,service,手机,float,delay,protocols)