目录
1.Android传感器概述(一)
传感器是一种微型的物理设备, 能够探测、感受到外界信号, 并按一定规律转换成我们需要的信息。在Android系统中,提供了用于接收这些信息并传递给我们的API。利用这些API就可以开发出想要的功能。
Android系统中的传感器可用于监视设备的移动和位置以及周围环境的变化。例如,实现微信摇一摇功能时,可以使用加速度传感器来监听各个方向的加速度值;实现神庙逃亡游戏时,可以使用方向传感器来实现倾斜设备变道功能。
1-1.Android 的常用传感器
目前市场上很多App都使用到传感器。比如在一些App中可以自动识别屏 幕的横屏或竖屏方向来改变屏幕布局,这是因为手机硬件支持重力感应和方向判断等功能。实际上Android系统对所有类型的传感器的处理都是一样的,只是传感器的类型有所区别。
与传感器硬件进行交互需要使用Sensor对象。Sensor 对象描述了它们代表的硬件传感器的属性,其中包括传感器的类型、名称、制造商以及与精确度和范围有关的详细信息。
Sensor类包含了一组常量, 这些常量描述了一个特定的 Scensor对象所表示的硬件传感器的类型 。形式为Sensor.TYPE_<TYPE>。 在Android中支持的传感器的类型如表13.1 所示。
表13.1 Android中支持的传感器类型
| 名称 | 传感器类型常量 | 描述 |
|---|---|---|
| 加速度传感器 | Sensor.TYPE_ACCELEROMETER | 用于获取Android设备在X、Y、Z三个坐标轴方向上的加速度,单位为m/s² |
| 重力传感器 | Sensor.TYPE_GRAVITY | 返回一个三维向量,这个三维向量可显示重力的方向和强度,单位为m/s²。其坐标系统与加速度传感器的坐标系统相同 |
| 线性加速度传感器 | Sensor.TYPE_LINEAR ACCELEROMETER | 用于获取Android设备在X、Y、Z三个坐标轴方向上不包括重力的加速度,单位为m/s²。加速度传感器、重力传感器和线性加速度传感器这三者输出值的计算公式如下:加速度=重力+线性加速度 |
| 陀螺仪传感器 | Sensor.TYPE_GYROSCOPE | 用于获取Android设备在X、Y、Z这三个坐标轴方向上的旋转速度,单位是弧度/秒。该值为正值时代表逆时针旋转,该值为负值时代表顺时针旋转 |
| 光线传感器 | Sensor.TYPE_LIGHT | 用于获取Android设备所处外界环境的光线强度,单位是勒克斯(Lux 简称lx) |
| 磁场传感器 | Sensor.TYPE_MAGNETIC_FIELD | 用于获取Android设备在X、Y、Z三个坐标轴方向上的磁场数据,单位是微特斯拉(μT) |
| 方向传感器 | Sensor.TYPE_ORIENTATION | 返回三个角度,这三个角度可以确定设备的摆放状态 |
| 压力传感器 | Sensor.TYPE_PRESSURE | 用于获取Android设备所处环境的压力的大小,单位为毫巴(millibars) |
| 距离传感器 | Sensor.TYPE_PROXIMITY | 用于检测物体与Android设备的距离,单位是厘米。一些距离传感器只能返回 “远”和“近”两个状态,“远”表示传感器的最大工作范围,而“近”是指比该范围小的任何值 |
| 温度传感器 | Sensor.TYPE_AMBIENT_TEMPERATURE | 用于获取Android设备所处环境的温度,单位是摄氏度。这个传感器是在Android4.0中引入的,用于代替已被弃用的Sensor.TYPE_TEMPERATURE |
| 相对湿度传感器 | Sensor.TYPE_RELATIVE_HUMIDITY | 用于获取Android设备所处环境的相对湿度,以百分比的形式表示。这个传感器是在Android 4.0中引入的 |
| 旋转矢量传感器 | Sensor.TYPE_ROTATION_VECTOR | 返回设备的方向,它表示为X、Y、Z三个坐标轴的角度的组合,是一个将坐标轴和角度混合计算得到的数据 |
注:虽然Android系统中支持多种传感器类型,但并不是每个Android设备都完全支持这些传感器。
1-2.开发步骤
应用开发传感器大致需要经过以下3个步骤:
(1)调用Context的getSystemService(Context.SENSOR_SERVICE) 方法来获取SensorManager对象。SensorManager是所有传感器的一个综合管理类, 包括了传感器的种类、 采样率、精准度等。 调用Context的getSystemService()方法的代码如下:
SensorManager sensorManager = (SensorManager)getSystemService(Context SENSOR_SERVICE);
(2)调用SensorManager的getDefaultSensor(int type)方法来获取指定类型的传感器。例如,返回默认的压力传感器的代码如下:
Sensor defaultPressure = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);
(3)在Activity的onResume()方法中调用SensorManager的registerListener()方法为指定传感器注册监听器。程序通过实现监听器即可获取传感器传回来的数据。调用registerListener()方法的语法格式如下:
sensorManager.registerListener(SensorEventListener listener, Sensor sensor, int rate)
参数说明如下:
◆ listener:监听传感器事件的监听器。该监听器需要实现SensorEventListener 接口。
◆sensor:传感器对象。
◆rate:指定获取传感器数据的频率,它支持的频率值如表12.2 所示。
表13.2 获取传感器数据的频率值
| 频率值 | 描述 |
|---|---|
| SensorManager.SENSOR_DELAY_FASTEST | 尽可能快地获得传感器数据,延迟最小 |
| SensorManager.SENSOR_ DELAY_ GAME | 适合游戏的频率 |
| SensorManager.SENSOR_DELAY_ NORMAL | 正常频率 |
| SensorManager.SENSOR_DELAY_UI | 适合普通用户界面的频率,延迟较大 |
例如,使用正常频率为默认的压力传感器注册监听器的代码如下:
sensorManager.registerListener(this, defaultPressure, SensorManager.SENSOR_DELAY_NORMAL);
◆SensorEventListener 是使用传感器的核心,其中需要实现的两个方法如下:
◎onSensorChanged(SensorEvent event)方法
该方法在传感器的值发生改变时调用。其参数是一个SensorEvent对象,通过该对象的values属性可以获取传感器的值,该值是一个包含了已检测到的新值的浮点型数组。不同传感器所返回的值的个数及其含义是不同的。不同传感器的返回值的详细信息如表13.3 所示。
表13.3 传感器的返回值
| 传感器名称 | 值的数量 | 值的构成 | 注释 |
|---|---|---|---|
| 重力传感器 | 3 | value[0]:X轴 value[1]:Y轴 value[2]:Z轴 | 沿着三个坐标轴以m/s²为单位的重力 |
| 加速度传感器 | 3 | value[0]:X轴 value[1]:Y轴 value[2]:Z轴 | 沿着三个坐标轴以m/s²为单位的加速度 |
| 线性加速度传感器 | 3 | value[0]:X轴 value[1]:Y轴 value[2]:Z轴 | 沿着三个坐标轴以m/s²为单位的加速度,不包含重力 |
| 陀螺仪传感器 | 3 | value[0]:X轴 value[1]:Y轴 value[2]:Z轴 | 绕三个坐标轴的旋转速率,单位是弧度/秒 |
| 光线传感器 | 1 | value[0]:照度 | 以勒克斯(Lux)为单位测量的外界光线强度 |
| 磁场传感器 | 3 | value[0]:X轴 value[1]:Y轴 value[2]:Z轴 | 以微特斯拉为单位表示的环境磁场 |
| 方向传感器 | 3 | value[0]:X轴 value[1]:Y轴 value[2]:Z轴 | 以角度确定设备的摆放状态 |
| 压力传感器 | 1 | value[0]:气压 | 以毫巴为单位测量的气压 |
| 距离传感器 | 1 | value[0]:距离 | 以厘米为单位测量的设备与目标的距离 |
| 温度传感器 | 1 | value[0]:温度 | 以摄氏度为单位测量的环境温度 |
| 相对湿度传感器 | 1 | value[0]:相对湿度 | 以百分比形式表示的相对湿度 |
| 旋转矢量传感器 | 3(还有一个可选参数) | value[0]:x*sin(θ/2) value[1]:y*sin( θ/2) value[2]:z*sin(θ/2) valuc[3]:cos(θ/2) (可选) | 设备方向,以绕坐标轴的旋转角度表示 |
传感器的坐标系统和Android设备屏幕的坐标系统不同。对于大多数传感器来说,其坐标系统的X轴方向沿屏幕向右,Y轴方向沿屏幕向上,Z轴方向是垂直屏幕向上。
注:在Android设备屏幕的方向发生改变时,传感器坐标系统的各坐标轴不会发生变化,即传感器的坐标系统不会因设备的移动而改变。
◎onAccuracyChanged(Sensor sensor, int accuracy)方法
该方法在传感器的精度发生改变时调用。参数sensor表示传感器对象,参数accuracy表示该传感器新的精度值。
以上就是开发传感器的3个步骤。除此之外,当应用程序不再需要接收更新时,需要注销其传感器事件监听器,代码如下:
sensorManager.unregisterListener(this);
注:Android 模拟器本身并没有提供传感器的功能,开发者需要把程序安装在Android手机中运行即可。
例:

MainActivity.java
package com.example.sensortest;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private TextView tv_gravity;//声明显示重力的文本框
private EditText et_gravity;//声明显示重力的编辑框
private TextView tv_light;//声明显示光线的文本框
private EditText et_light;//声明显示光线的编辑框
private SensorManager sensorManager;//定义传感器管理器
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar=getSupportActionBar();
actionBar.hide();
tv_gravity=findViewById(R.id.main_tv1);
et_gravity=findViewById(R.id.main_et1);
tv_light=findViewById(R.id.main_tv2);
et_light=findViewById(R.id.main_et2);
sensorManager= (SensorManager) getSystemService(SENSOR_SERVICE);
}
@Override
protected void onResume() {
super.onResume();
//为重力传感器注册监听器
sensorManager.registerListener(this,sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY),
SensorManager.SENSOR_DELAY_GAME);
//为光线传感器注册监听器
sensorManager.registerListener(this,sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT),
SensorManager.SENSOR_DELAY_GAME);
}
@Override
protected void onPause() {
super.onPause();
//取消注册的监听器
sensorManager.unregisterListener(this);
}
@Override
protected void onStop() {
super.onStop();
//取消注册的监听器
sensorManager.unregisterListener(this);
}
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
float[] values=sensorEvent.values;//获取X、Y、Z三个坐标轴的输出信息
int sensorType=sensorEvent.sensor.getType();//获取传感器类型
switch (sensorType){
case Sensor.TYPE_GRAVITY:
StringBuilder stringBuilder=new StringBuilder();
stringBuilder.append("X轴横向重力值:");
stringBuilder.append(values[0]);
stringBuilder.append("\nY轴纵向重力值:");
stringBuilder.append(values[1]);
stringBuilder.append("\nZ轴向上重力值:");
stringBuilder.append(values[2]);
et_gravity.setText(stringBuilder.toString());
break;
case Sensor.TYPE_LIGHT:
stringBuilder=new StringBuilder();
stringBuilder.append("光的强度值:");
stringBuilder.append(values[0]);
et_light.setText(stringBuilder.toString());
break;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
}
本文介绍了Android系统中的传感器,包括传感器的概念、用途,如加速度传感器在微信摇一摇功能中的应用,以及方向传感器在游戏中的作用。文章详细阐述了Android中常用传感器的类型,并提供了开发传感器应用的三个步骤:获取SensorManager对象、获取指定传感器和注册监听器。最后,解释了SensorEventListener接口中的关键方法onSensorChanged和onAccuracyChanged。
3162

被折叠的 条评论
为什么被折叠?



