Android 传感器(Sensor)API教程 (四) 加速度传感器

来源:互联网 发布:梁宁 闲花照水录 知乎 编辑:程序博客网 时间:2024/05/21 13:23

原帖地址:http://www.androidegg.com/portal.php?mod=view&aid=612

1.4 加速度传感器
    加速度传感器是为了检测物体的加速度的传感器。物体运动加速度也跟着变化,如果能取到加速度,物体受到什么样的作用力或则物体进行什么样的运动,我们就可以知道。使用加速度,我们就能做模拟计步器、物体运动的应用程序。
1.4.1  通过加速度传感器能取到的值
  
我们可以通过Android的加速度传感器可以取得x,y,z三个轴的加速度(如图1-4)。
   加速度值受地球重力的影响值也不一样。这就涉及到物理知识了,我就不细阐述了。也不是一句两句能说清楚的。在SensorManager类中定义了很多星体的重力加速度值。如表1-7
   

   图 1-4 加速度传感器的轴
表1-7 SensorManager 类被定义的各新星体的重力加速度值
常量名
说明
实际的值
GRAVITY_DEATH_STAR_1
死亡星
3.5303614E-7
GRAVITY_EARTH
地球
9.80665
GRAVITY_JUPITER
木星
23.12
GRAVITY_MARS
火星
3.71
GRAVITY_MERCURY
水星
3.7
GRAVITY_MOON
月亮
1.6
GRAVITY_NEPTUNE
海王星
11.0
GRAVITY_PLUTO
冥王星
0.6
GRAVITY_SATURN
土星
8.96
GRAVITY_SUN
太阳
275.0
GRAVITY_THE_ISLAND
岛屿星
4.815162
GRAVITY_URANUS
天王星
8.69
GRAVITY_VENUS
金星
8.87

1.4.2  只想保留重力的影响的时候
    
通常,从加速度传感器取得的值,拿手机手机设备的人的手震动或则放在摇晃的场所的时候,受震动影响设备的值增幅变化是存在的。手的摇动、轻微震动的影响是属于长波形式,去掉这种长波干扰的影响,可以取得高精度的值。去掉这种长波这种过滤机能叫
Low-Pass Filter。
    Low-Pass Filter的封装方法如下面所述。

         ・从抽样数据中取得中间的值的方法
         
最近取得的加速度的值每个很少变化的方法

     ●从抽样数据中取得中间的值的方法  
     从抽样数据取得中间值的抽样代码如下 列表1-3所示。并且,抽样数为30来做的,根据封装的程序的用途和传感器的感度进行调整。
       列表1-3 从抽样数据中取得中间值
package androidegg.stu.sensor;

import java.util.Arrays;
import java.util.List;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;

public class AndroidEggSensorGetValueActivity extends Activity implements SensorEventListener{
    /** Called when the activity is first created. */
    private SensorManager sensorManager;
    private static final int ELEMENT_COUNT = 30;
    
    //Data
    private float[] samplingX = new float[ELEMENT_COUNT];      //..................①
    private float[] samplingY = new float[ELEMENT_COUNT];
    private float[] samplingZ = new float[ELEMENT_COUNT];
    
    private int position;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //SensorManagerのインスタンスを取得
        sensorManager = (SensorManager)this.getSystemService(SENSOR_SERVICE);
        setContentView(R.layout.main);
    }
    
    @Override
    protected void onResume(){
        super.onResume();
        List sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
        
        //sensor1
        for (Sensor s : sensors){
            sensorManager.registerListener(this,s,SensorManager.SENSOR_DELAY_NORMAL);
        }              
    }
    
    //
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void onSensorChanged(SensorEvent e) {
        if (position == ELEMENT_COUNT - 1){                                         
//..................②
            position =0;
        }else{
            position++;
        }
        float x = e.values[sensorManager.DATA_X];
        float y = e.values[sensorManager.DATA_Y];
        float z = e.values[sensorManager.DATA_Z];
        
        samplingX[position] = x;
        samplingY[position] = y;
        samplingZ[position] = z;
        
        TextView textX = (TextView)findViewById(R.id.x);
        textX.setText("x:" + String.valueOf(getMedian(samplingX)));
        TextView textY = (TextView)findViewById(R.id.y);
        textY.setText("y:" + String.valueOf(getMedian(samplingY)));
        TextView textZ = (TextView)findViewById(R.id.z);
        textZ.setText("Z:" + String.valueOf(getMedian(samplingZ)));
    }  
    
    private float getMedian(float[] values) {         
//..................③
        // TODO Auto-generated method stub
        float[] tmp = values.clone();
        Arrays.sort(tmp);
        int len = tmp.length;
        int first = 0;
        
        for (int i =0;i
            first =i;
        }
        return tmp[(len - first)/2 + first];
    }

    //
    @Override
    protected void onStop(){
        super.onStop();
        sensorManager.unregisterListener(this);
    }
}
         
运行结果如图1-5

重要注意点如下所示
     ①x,y,z 轴的各个保存用的数组定义
     ②抽样用的数据从数组的0开始的顺序保存,到第29个的时候再从0开始保存
     ③数组保存的值的中间值取得
最近取得的加速度的值每个很少变化的方法
   例程如列表1-4
       并且,在例程中取得的值增加10%,封装的应用程序要根据传感器的感应度进行调整。
      
       列表 1-4 
最近取得的加速度的值每个很少变化的方法的例程
package androidegg.stu.sensor;

import java.util.Arrays;
import java.util.List;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;

public class AndroidEggSensorGetValueActivity extends Activity implements SensorEventListener{
    /** Called when the activity is first created. */
    private SensorManager sensorManager;           

    //
    private  final float FILTERING_VALAUE = 0.1f;
    private float lowX,lowY,lowZ;                       
//..................①
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //SensorManagerのインスタンスを取得
        sensorManager = (SensorManager)this.getSystemService(SENSOR_SERVICE);
        setContentView(R.layout.main);
    }
    
    @Override
    protected void onResume(){
        super.onResume();
        List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
        
        //sensor1
        for (Sensor s : sensors){
            sensorManager.registerListener(this,s,SensorManager.SENSOR_DELAY_NORMAL);
        }              
    }
    
    //
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // TODO Auto-generated method stub
        
    }

    @Override
    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];
        
        //
        lowX = x * FILTERING_VALAUE + lowX * (1.0f - FILTERING_VALAUE);  
//..................②
        lowY = y * FILTERING_VALAUE + lowY * (1.0f - FILTERING_VALAUE);
        lowZ = z * FILTERING_VALAUE + lowZ * (1.0f - FILTERING_VALAUE);

        TextView textX = (TextView)findViewById(R.id.x);
        textX.setText("x:" + String.valueOf(lowX));
        TextView textY = (TextView)findViewById(R.id.y);
        textY.setText("y:" + String.valueOf(lowY));
        TextView textZ = (TextView)findViewById(R.id.z);
        textZ.setText("Z:" + String.valueOf(lowZ));
    }  
    


    //
    @Override
    protected void onStop(){
        super.onStop();
        sensorManager.unregisterListener(this);
    }
}

     
运行结果如图1-5-1

重要注意点如下所示
     ①Low-Pass Filter处理的值保存的变量的定义
     ②取得的传感器的值的10%加上上回取得的90%