您的位置:首页 > 其它

传感器

2015-09-24 17:29 429 查看
手机中内置的传感器是一种微型的物理设备,它能够探测、感受到外界的信号,并按一定规律转换成我们所需要的信息。Android手机通常都会支持多种类型的传感器,如光照传感右器、加速度传感器、地磁传感器、压力传感器、温度传感器等。

当然,Android系统只是负责将这些传感器所输出的信息传递给我们,至于具体如何去利用这些信息就要充分发挥开发者的想象力了。目前市场上很多的程序都有使用到传感器的功能,比如最常见的赛车游戏,玩家可以通过旋转设备来控制赛车的前进方向,就像是在操作方向盘一样。除此之外,微信的摇一摇功能,手机指南针等软件也都是借助传感器来完成的。

Android中每个传感器的用法其实都比较类似,真的可以说是一通百通了。

1.光照传感器

简单的利用光照传感器的小例子,实现检测当前光照强度

public class MainActivity extends Activity {
private TextView tv;
private SensorManager manager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView) findViewById(R.id.tv);
manager=(SensorManager) getSystemService(Context.SENSOR_SERVICE);
//      SensorManager是系统所有传感器的管理器,有了它的实例之后就可以调用getDefaultSensor()方法来得到任意的传感器类型了
Sensor sensor = manager.getDefaultSensor(Sensor.TYPE_LIGHT);
//registerListener()方法接收三个参数,第一个参数就是SensorEventListener的实例,
//      第二个参数是Sensor的实例,这两个参数我们在前面都已经成功得到了。
//      第三个参数是用于表示传感器输出信息的更新速率,共有SENSOR_DELAY_UI、SENSOR_DELAY_NORMAL、
//      SENSOR_DELAY_GAME和SENSOR_DELAY_FASTEST这四种值可选,它们的更新速率是依次递增的。
manager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
}

@Override
protected void onDestroy() {
super.onDestroy();
if (manager != null) {
manager.unregisterListener(listener);
}
}
/**
* 对传感器输出的信号进行监听
* 当传感器的精度发生变化时就会调用onAccuracyChanged()方法,
* 当传感器监测到的数值发生变化时就会调用onSensorChanged()方法。
* */
private SensorEventListener listener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
//      SensorEvent参数里包含了一个values数组,所有传感器输出的信息都是存放在这里的。
// values数组中第一个下标的值就是当前的光照强度
float value = event.values[0];
tv.setText("Current light level is " + value + " lx");//勒克斯为单位
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {

}
};
}


2.加速度传感器

利用加速度传感器来模仿一下微信的摇一摇功能。其实主体逻辑也非常简单,只需要检测手机在X轴、Y轴和Z轴上的加速度,当达到了预定值的时候就可以认为用户摇动了手机,从而触发摇一摇的逻辑。那么现在问题在于,这个预定值应该设定为多少呢?由于重力加速度的存在,即使手机在静止的情况下,某一个轴上的加速度也有可能达到9.8m/s2,因此这个预定值必定是要大于9.8m/s2的,这里我们就设定为15m/s2吧。

public class MainActivity extends Activity {
private TextView tv;
private SensorManager manager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView) findViewById(R.id.tv);
manager=(SensorManager) getSystemService(Context.SENSOR_SERVICE);
//      SensorManager是系统所有传感器的管理器,有了它的实例之后就可以调用getDefaultSensor()方法来得到任意的传感器类型了
Sensor sensor = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
//registerListener()方法接收三个参数,第一个参数就是SensorEventListener的实例,
//      第二个参数是Sensor的实例,这两个参数我们在前面都已经成功得到了。
//      第三个参数是用于表示传感器输出信息的更新速率,共有SENSOR_DELAY_UI、SENSOR_DELAY_NORMAL、
//      SENSOR_DELAY_GAME和SENSOR_DELAY_FASTEST这四种值可选,它们的更新速率是依次递增的。
manager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
}

@Override
protected void onDestroy() {
super.onDestroy();
if (manager != null) {
manager.unregisterListener(listener);
}
}
/**
* 对传感器输出的信号进行监听
* 当传感器的精度发生变化时就会调用onAccuracyChanged()方法,
* 当传感器监测到的数值发生变化时就会调用onSensorChanged()方法。
* */
private SensorEventListener listener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
//      SensorEvent参数里包含了一个values数组,所有传感器输出的信息都是存放在这里的。
//          values数组中会有三个值,分别代表手机在X轴、Y轴和Z轴方向上的加速度信息。
// 加速度可能会是负值,所以要取它们的绝对值
float xValue = Math.abs(event.values[0]);
float yValue = Math.abs(event.values[1]);
float zValue = Math.abs(event.values[2]);
if (xValue > 15 || yValue > 15 || zValue > 15) {
// 认为用户摇动了手机,触发摇一摇逻辑
Toast.makeText(MainActivity.this, "摇一摇", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {

}
};
}


3.方向传感器

方向传感器的使用场景要比其他的传感器更为广泛,它能够准确地判断出手机在各个方向的旋转角度,利用这些角度就可以编写出像指南针、地平仪等有用的工具。

简易指南针

public class MainActivity extends Activity {
private SensorManager sensorManager;
private ImageView compassImg;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
compassImg = (ImageView) findViewById(R.id.compass_img);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
//Android获取手机旋转的方向和角度是通过加速度传感器和地磁传感器共同计算得出的
Sensor magneticSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
Sensor accelerometerSensor = sensorManager.getDefaultSensor(
Sensor.TYPE_ACCELEROMETER);
//由于方向传感器的精确度要求通常都比较高,这里我们把传感器输出信息的更新速率提高了一些,使用的是SENSOR_DELAY_GAME。
sensorManager.registerListener(listener, magneticSensor,
SensorManager.SENSOR_DELAY_GAME);
sensorManager.registerListener(listener, accelerometerSensor,
SensorManager.SENSOR_DELAY_GAME);
}

private SensorEventListener listener = new SensorEventListener() {
float[] accelerometerValues = new float[3];
float[] magneticValues = new float[3];
private float lastRotateDegree;

@Override
public void onSensorChanged(SensorEvent event) {
// 判断当前是加速度传感器还是地磁传感器
//          SensorEvent的values数组记录着加速度传感器和地磁传感器输出的值
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
// 注意赋值时要调用clone()方法
accelerometerValues = event.values.clone();
} else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
// 注意赋值时要调用clone()方法
magneticValues = event.values.clone();
}
float[] values = new float[3];
float[] R = new float[9];
//得到一个包含旋转矩阵的R数组
//          第一个参数R是一个长度为9的float数组,getRotationMatrix()方法计算出的旋转数据就会赋值到这个数组当中。
//          第二个参数是一个用于将地磁向量转换成重力坐标的旋转矩阵,通常指定为null即可。
//          第三和第四个参数则分别就是加速度传感器和地磁传感器输出的values值。
SensorManager.getRotationMatrix(R, null, accelerometerValues,
magneticValues);
//计算手机的旋转数据
//,手机在各个方向上的旋转数据都会被存放到这个数组当中。
//          其中values[0]记录着手机围绕着图12.3中Z轴的旋转弧度,
//          values[1]记录着手机围绕X轴的旋转弧度,
//          values[2]记录着手机围绕Y轴的旋转弧度。
//          values[0]的取值范围是180度到180度,其中±180度表示正南方向,0度表示正北方向,
//          90度表示正西方向,90度表示正东方向。
SensorManager.getOrientation(R, values);
// 将计算出的旋转角度取反,用于旋转指南针背景图

//          Math.toDegrees 弧度转化为角度 Math.toRadians 角度转化为弧度
float rotateDegree = -(float) Math.toDegrees(values[0]);
//绝对值>1
if (Math.abs(rotateDegree - lastRotateDegree) > 1) {

//              旋转动画技术,我们创建了一个RotateAnimation的实例,并给它的构造方法传入了六个参数,
//              第一个参数表示旋转的起始角度,第二个参数表示旋转的终止角度,
//              后面四个参数用于指定旋转的中心点。这里我们把从传感器中获取到的旋转角度取反,传递给RotateAnimation,
//              并指定旋转的中心点为指南针背景图的中心,然后调用ImageView的startAnimation ()方法来执行旋转动画。
RotateAnimation animation = new RotateAnimation(
lastRotateDegree, rotateDegree,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
animation.setFillAfter(true);
compassImg.startAnimation(animation);
lastRotateDegree = rotateDegree;
}
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub

}
};
}


准备好了两张图片compass.png和arrow.png,分别用于作为指南针的背景和指针



布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/compass_img"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_centerInParent="true"
android:src="@drawable/compass" />
<ImageView
android:id="@+id/arrow_img"
android:layout_width="60dp"
android:layout_height="110dp"
android:layout_centerInParent="true"
android:src="@drawable/arrow" />
</RelativeLayout>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息