1.Android传感器概述(1)
1-1.Android 常用传感器
1-2.开发步骤
1.Android传感器概述(1)
传感器是一种微型物理设备, 能够探测和感受到外部信号, 并将其转换为我们需要的信息。Android在系统中,它提供接收和传递给我们的信息API。利用这些API您可以开发所需的功能。
Android系统中的传感器可用于监控设备的移动和位置以及周围环境的变化。例如,在实现微信摇功能时,可以使用加速度传感器监控各方向的加速度值;在实现寺庙逃生游戏时,可以使用方向传感器来实现倾斜设备的变道功能。
1-1.Android 常用传感器
市场上有很多App都用传感器。例如,在某些方面。App屏幕可以自动识别 由于手机硬件支持重力感应和方向判断等功能,屏幕的水平或垂直屏幕方向会改变屏幕布局。Android系统对所有类型的传感器都有相同的处理,但传感器的类型不同。
与传感器硬件交互需要使用Sensor对象。Sensor 对象描述了它们所代表的硬件传感器的属性,包括传感器的类型、名称、制造商和与精度和范围相关的详细信息。
Sensor类包含一组常量, 这些常量描述了一个特定的 Scensor硬件传感器硬件传感器类型 。形式为Sensor.TYPE_<TYPE>。 在Android支持的传感器类型如表13.1 所示。
名称 | 传感器类型常量 | 描述 |
---|---|---|
加速传感器 | Sensor.TYPE_ACCELEROMETER | 用于获取Android设备在X、Y、Z三个坐标轴方向的加速度为m/s2 |
重力传感器 | Sensor.TYPE_GRAVITY | 返回三维向量,可显示重力的方向和强度,单位为m/s2。其坐标系统与加速度传感器的坐标系统相同 |
线性加速度传感器 | Sensor.TYPE_LINEAR ACCELEROMETER | 用于获取Android设备在X、Y、Z三个坐标轴不包括重力的加速度,单位为m/s2.加速度传感器、重力传感器和线性加速度传感器的输出值计算公式如下:加速度=重力 线性加速度 |
陀螺仪传感器 | 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.开发步骤
大致需要三个步骤来开发传感器:
(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 所示。
频率值 | 描述 |
---|---|
SensorManager.SENSOR_DELAY_FASTEST | 尽快获取传感器数据,最小延迟 |
SensorManager.SENSOR_ DELAY_ GAME | 适合游戏频率 |
SensorManager.SENSOR_DELAY_ NORMAL | 正常频率 |
SensorManager.SENSOR_DELAY_UI | 适用于普通用户界面的频率,延迟较大 |
例如,默认压力传感器注册监听器的代码如下:
sensorManager.registerListener(this, defaultPressure, SesorManager.SENSOR_DELAY_NORMAL);
◆SensorEventListener 是使用传感器的核心,其中需要实现的两个方法如下:
◎onSensorChanged(SensorEvent event)方法
该方法在传感器的值发生改变时调用。其参数是一个SensorEvent对象,通过该对象的values属性可以获取传感器的值,该值是一个包含了已检测到的新值的浮点型数组。不同传感器所返回的值的个数及其含义是不同的。不同传感器的返回值的详细信息如表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手机中运行即可。
例:
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) {
}
}