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
——延时:0msSENSOR_DELAY_GAME
——延时:20msSENSOR_DELAY_UI
——延时:60msSENSOR_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和SensorManager实现手机旋转角度