Android Sensor应用

Posted Dufre.WC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Sensor应用相关的知识,希望对你有一定的参考价值。

文章目录

Sensor types supported by the android Platform

Android支持的Sensor Type可以在/hardware/libhardware/include/hardware/sensor.h中查看,这里我截图过来了。

Classes and Interfaces

Sensor Manager

可以用SensorManager这个类创建sensor service的一个实例,它包含了:

  • listing sensor
  • registering and unregistering sensor listeners
  • acquiring orientation information

Sensor

可以用Sensor创建一个具体Sensor的实例,提供了获取该Sensor的特性。

SensorEvent

可以用SensorEvent类创建一个SensorEvent的对象,提供以下信息:

  • raw sensor data
  • type of sensor that generated the event
  • accuracy of the data
  • timestamp for the event

SensorEventListener

可以用这个接口创建两个回调函数去接收通知(sensor events)

  • sensor value改变时(onSensorChanged())
  • sensor accuracy改变时(onAccuracyChanged())

API and Example

使用步骤

Step1:获得传感器管理器

SensorManager mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); 

Step2:调用特定方法获得所需的传感器

Sensor mPressure = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);

Step3:实现SensorEventListener接口,重写onSensorChanged和onAccuracyChanged的方法。

    @Override
    public final void onAccuracyChanged(Sensor sensor, int accuracy) 
      // Do something here if sensor accuracy changes.
    

    @Override
    public final void onSensorChanged(SensorEvent event) 
      float millibarsOfPressure = event.values[0];
      // Do something with this sensor data.
    

Step4:SensorManager对象调用registerListener注册监听器,需要传入三个参数:

  • 上下文对象
  • Sensor传感器对象
  • 传感器的延时时间的精度密度
mSensorManager.registerListener(this, mPressure, SensorManager.SENSOR_DELAY_NORMAL);

其中传感器器延时时间的精度密度有四种:

  • SENSOR_DELAY_FASTEST——延时:0ms
  • SENSOR_DELAY_GAME——延时:20ms
  • SENSOR_DELAY_UI——延时:60ms
  • SENSOR_DELAY_NORMAL——延时:200ms
    低延时意味着频繁的检测,但是也意味着功耗越大,所以如果不是精度要求非常高,还是建议用第三个或者第四个。

Step5:监听器的取消注册

mSensorManager.unregisterListener(this);

Example

Motion sensors

Use the accelerometer

private SensorManager sensorManager;
private Sensor sensor;
  ...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

public void onSensorChanged(SensorEvent event)
    // In this example, alpha is calculated as t / (t + dT),
    // where t is the low-pass filter's time-constant and
    // dT is the event delivery rate.

    final float alpha = 0.8;

    // Isolate the force of gravity with the low-pass filter.
    gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
    gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
    gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];

    // Remove the gravity contribution with the high-pass filter.
    linear_acceleration[0] = event.values[0] - gravity[0];
    linear_acceleration[1] = event.values[1] - gravity[1];
    linear_acceleration[2] = event.values[2] - gravity[2];

Use the gyroscope

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);

// Create a constant to convert nanoseconds to seconds.
private static final float NS2S = 1.0f / 1000000000.0f;
private final float[] deltaRotationVector = new float[4]();
private float timestamp;

public void onSensorChanged(SensorEvent event) 
    // This timestep's delta rotation to be multiplied by the current rotation
    // after computing it from the gyro sample data.
    if (timestamp != 0) 
      final float dT = (event.timestamp - timestamp) * NS2S;
      // Axis of the rotation sample, not normalized yet.
      float axisX = event.values[0];
      float axisY = event.values[1];
      float axisZ = event.values[2];

      // Calculate the angular speed of the sample
      float omegaMagnitude = sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);

      // Normalize the rotation vector if it's big enough to get the axis
      // (that is, EPSILON should represent your maximum allowable margin of error)
      if (omegaMagnitude > EPSILON) 
        axisX /= omegaMagnitude;
        axisY /= omegaMagnitude;
        axisZ /= omegaMagnitude;
      

      // Integrate around this axis with the angular speed by the timestep
      // in order to get a delta rotation from this sample over the timestep
      // We will convert this axis-angle representation of the delta rotation
      // into a quaternion before turning it into the rotation matrix.
      float thetaOverTwo = omegaMagnitude * dT / 2.0f;
      float sinThetaOverTwo = sin(thetaOverTwo);
      float cosThetaOverTwo = cos(thetaOverTwo);
      deltaRotationVector[0] = sinThetaOverTwo * axisX;
      deltaRotationVector[1] = sinThetaOverTwo * axisY;
      deltaRotationVector[2] = sinThetaOverTwo * axisZ;
      deltaRotationVector[3] = cosThetaOverTwo;
    
    timestamp = event.timestamp;
    float[] deltaRotationMatrix = new float[9];
    SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector);
    // User code should concatenate the delta rotation we computed with the current rotation
    // in order to get the updated rotation.
    // rotationCurrent = rotationCurrent * deltaRotationMatrix;

Position sensors

Use the proximity sensor

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);

public class SensorActivity extends Activity implements SensorEventListener 
    private SensorManager sensorManager;
    private Sensor proximity;

    @Override
    public final void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Get an instance of the sensor service, and use that to get an instance of
        // a particular sensor.
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        proximity = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
    

    @Override
    public final void onAccuracyChanged(Sensor sensor, int accuracy) 
        // Do something here if sensor accuracy changes.
    

    @Override
    public final void onSensorChanged(SensorEvent event) 
        float distance = event.values[0];
        // Do something with this sensor data.
    

    @Override
    protected void onResume() 
        // Register a listener for the sensor.
        super.onResume();
        sensorManager.registerListener(this, proximity, SensorManager.SENSOR_DELAY_NORMAL);
      

    @Override
    protected void onPause() 
        // Be sure to unregister the sensor when the activity pauses.
        super.onPause();
        sensorManager.unregisterListener(this);
    

Environment sensors

环境sensor一般就一个数值,因此用法都是类似的,这里以pressure为例。

public class SensorActivity extends Activity implements SensorEventListener 
    private SensorManager sensorManager;
    private Sensor pressure;

    @Override
    public final void onCreate(Bundle savedInstanceState) 
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);

      // Get an instance of the sensor service, and use that to get an instance of
      // a particular sensor.
      sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
      pressure = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);
    

    @Override
    public final void onAccuracyChanged(Sensor sensor, int accuracy) 
      // Do something here if sensor accuracy changes.
    

    @Override
    public final void onSensorChanged(SensorEvent event) 
      float millibarsOfPressure = event.values[0];
      // Do something with this sensor data.
    

    @Override
    protected void onResume() 
      // Register a listener for the sensor.
      super.onResume();
      sensorManager.registerListener(this, pressure, SensorManager.SENSOR_DELAY_NORMAL);
    

    @Override
    protected void onPause() 
      // Be sure to unregister the sensor when the activity pauses.
      super.onPause();
      sensorManager.unregisterListener(this);
    

以上是关于Android Sensor应用的主要内容,如果未能解决你的问题,请参考以下文章

Android Shake(Sensor) 服务,用于在应用程序后台进行抖动检测

如何在 Android 上使用 type_magnetic_field_uncalibrated-sensor?

Android Sensor Development

获取Android设备的方向,Sensor和SensorManager实现手机旋转角度

Android Sensor详解Sensor ADSP Sensor1 api使用

Android Sensor 介绍