在Android手机中,内置了很多传感器,最常见的就是重力传感器,我们最常用的,比如说在玩游戏时,使用手机控制移动的方法,还有一些其他的传感器,像温度传感器、湿度传感器、光传感器、加速度传感器等,我们在日常使用中,一般是用不到的,但是如果在开发过程中使用到这些传感器,还是要知道这些传感器的使用方法。
1、传感器管理类
在手机内置的传感器,有统一的管理类SensorManager
SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
在SensorManager
中,有getSensorList
方法,这个方法返回所有的传感器。
public List<Sensor> getSensorList(int type) {
// cache the returned lists the first time
List<Sensor> list;
final List<Sensor> fullList = getFullSensorList();
synchronized (mSensorListByType) {
list = mSensorListByType.get(type);
if (list == null) {
if (type == Sensor.TYPE_ALL) {
list = fullList;
} else {
list = new ArrayList<Sensor>();
for (Sensor i : fullList) {
if (i.getType() == type) {
list.add(i);
}
}
}
list = Collections.unmodifiableList(list);
mSensorListByType.append(type, list);
}
}
return list;
}
在List集合中有一个Sensor
类,在Sensor
类中有很多传感器的类型:
TYPE_ACCELEROMETER | 加速传感器 |
---|---|
TYPE_ORIENTATION | 方向传感器 |
TYPE_PRESSURE | 压力传感器 |
TYPE_PROXIMITY | 临近传感器 |
TYPE_TEMPERATURE | 温度传感器 |
TYPE_GRAVITY | 重力传感器 |
TYPE_LINEAR_ACCELERATION | 线性加速传感器 |
TYPE_ROTATION_VECTOR | 旋转向量传感器 |
TYPE_RELATIVE_HUMIDITY | 湿度传感器 |
TYPE_AMBIENT_TEMPERATURE | 温度传感器 |
TYPE_MAGNETIC_FIELD_UNCALIBRATED | 磁场传感器 |
TYPE_GAME_ROTATION_VECTOR | 游戏旋转向量传感器 |
TYPE_GYROSCOPE_UNCALIBRATED | 陀螺仪传感器 |
TYPE_STEP_DETECTOR | 计步器传感器 |
TYPE_STEP_COUNTER | 计步器传感器 |
TYPE_HEART_RATE | 心率传感器 |
TYPE_WAKE_GESTURE | 手势唤醒传感器 |
TYPE_GLANCE_GESTURE | 掠过手势传感器 |
TYPE_HEART_BEAT | 心跳传感器 |
TYPE_LIGHT | 光线传感器 |
还有很多传感器,就不在此一一列举出来,标注黑体的传感器就是比较重要的传感器,可能会在开发中使用到的传感器。
List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL);
for (Sensor sensor :
sensorList) {
Log.e("TAG","sensor==="+sensor);
}
通过getSensorList
可以查看当前手机支持的传感器有哪些,因为不是每个手机都可以支持所有的传感器。
2020-02-10 20:11:56.710 13572-13572/? E/TAG: sensor==={Sensor name="ICM20690 Accelerometer", vendor="InvenSense", version=1, type=1, maxRange=78.4532, resolution=0.0023956299, power=0.325, minDelay=5000}
2020-02-10 20:11:56.710 13572-13572/? E/TAG: sensor==={Sensor name="ICM20690 Accelerometer Uncalibrated", vendor="InvenSense", version=1, type=35, maxRange=78.4532, resolution=0.0023956299, power=0.325, minDelay=5000}
2020-02-10 20:11:56.710 13572-13572/? E/TAG: sensor==={Sensor name="AK09916C Magnetometer", vendor="AKM", version=1, type=2, maxRange=4911.9995, resolution=0.14953613, power=1.1, minDelay=20000}
2020-02-10 20:11:56.710 13572-13572/? E/TAG: sensor==={Sensor name="AK09916C Magnetometer Uncalibrated", vendor="AKM", version=1, type=14, maxRange=4911.9995, resolution=0.14953613, power=1.1, minDelay=20000}
2020-02-10 20:11:56.711 13572-13572/? E/TAG: sensor==={Sensor name="ICM20690 Gyroscope", vendor="InvenSense", version=1, type=4, maxRange=34.906586, resolution=0.0010681152, power=2.5, minDelay=5000}
2020-02-10 20:11:56.711 13572-13572/? E/TAG: sensor==={Sensor name="ICM20690 Gyroscope Uncalibrated", vendor="InvenSense", version=1, type=16, maxRange=34.906586, resolution=0.0010681152, power=2.5, minDelay=5000}
2020-02-10 20:11:56.711 13572-13572/? E/TAG: sensor==={Sensor name="TMD2620 PROX", vendor="ams AG", version=2, type=8, maxRange=5.000305, resolution=1.0, power=0.1, minDelay=0}
2020-02-10 20:11:56.711 13572-13572/? E/TAG: sensor==={Sensor name="BMP285 Pressure", vendor="BOSCH", version=1040700, type=6, maxRange=1100.0, resolution=0.0018005371, power=0.025, minDelay=38461}
2020-02-10 20:11:56.711 13572-13572/? E/TAG: sensor==={Sensor name="ICM20690 Accelerometer -Wakeup Secondary", vendor="InvenSense", version=1, type=1, maxRange=78.4532, resolution=0.0023956299, power=0.325, minDelay=5000}
2020-02-10 20:11:56.711 13572-13572/? E/TAG: sensor==={Sensor name="ICM20690 Accelerometer Uncalibrated -Wakeup Secondary", vendor="InvenSense", version=1, type=35, maxRange=78.4532, resolution=0.0023956299, power=0.325, minDelay=5000}
2020-02-10 20:11:56.712 13572-13572/? E/TAG: sensor==={Sensor name="AK09916C Magnetometer -Wakeup Secondary", vendor="AKM", version=1, type=2, maxRange=4911.9995, resolution=0.14953613, power=1.1, minDelay=20000}
2020-02-10 20:11:56.712 13572-13572/? E/TAG: sensor==={Sensor name="AK09916C Magnetometer Uncalibrated -Wakeup Secondary", vendor="AKM", version=1, type=14, maxRange=4911.9995, resolution=0.14953613, power=1.1, minDelay=20000}
2020-02-10 20:11:56.712 13572-13572/? E/TAG: sensor==={Sensor name="ICM20690 Gyroscope -Wakeup Secondary", vendor="InvenSense", version=1, type=4, maxRange=34.906586, resolution=0.0010681152, power=2.5, minDelay=5000}
2020-02-10 20:11:56.712 13572-13572/? E/TAG: sensor==={Sensor name="ICM20690 Gyroscope Uncalibrated -Wakeup Secondary", vendor="InvenSense", version=1, type=16, maxRange=34.906586, resolution=0.0010681152, power=2.5, minDelay=5000}
通过getDefaultSensor
传入传感器的类型可以得到某个特定类型的传感器:
public Sensor getDefaultSensor(int type) {
// TODO: need to be smarter, for now, just return the 1st sensor
List<Sensor> l = getSensorList(type);
boolean wakeUpSensor = false;
// For the following sensor types, return a wake-up sensor. These types are by default
// defined as wake-up sensors. For the rest of the SDK defined sensor types return a
// non_wake-up version.
if (type == Sensor.TYPE_PROXIMITY || type == Sensor.TYPE_SIGNIFICANT_MOTION
|| type == Sensor.TYPE_TILT_DETECTOR || type == Sensor.TYPE_WAKE_GESTURE
|| type == Sensor.TYPE_GLANCE_GESTURE || type == Sensor.TYPE_PICK_UP_GESTURE
|| type == Sensor.TYPE_WRIST_TILT_GESTURE
|| type == Sensor.TYPE_DYNAMIC_SENSOR_META) {
wakeUpSensor = true;
}
for (Sensor sensor : l) {
if (sensor.isWakeUpSensor() == wakeUpSensor) return sensor;
}
return null;
}
比如说,我想使用温度传感器,那么就使用温度传感器的TYPE类型得到温度传感器,发现手机里没有温度传感器,我的是小米6手机,不知道其他的手机有没有,小米6已经好几年了,不知新代的手机有没有温度传感器。
Sensor temSensor = sensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE);
Log.e("TAG","tem==="+temSensor);
2020-02-10 20:22:17.740 14165-14165/com.example.sensor E/TAG: tem===null
那就挑一个加速传感器,这个在手机里是有的,我们测试一下返回的数据。
要想测试传感器返回的数据,需要注册监听器registerListener
,要注意一点是,要在onResume
方法中注册。
public boolean registerListener(SensorEventListener listener, Sensor sensor,
int samplingPeriodUs, int maxReportLatencyUs) {
int delay = getDelay(samplingPeriodUs);
return registerListenerImpl(listener, sensor, delay, null, maxReportLatencyUs, 0);
}
registerListener
有很多构造方法,还包括Handler字段,说明可以做回调,线程切换;除了这个,还有一个delay字段,这个字段是数据采集频率。
private static int getDelay(int rate) {
int delay = -1;
switch (rate) {
case SENSOR_DELAY_FASTEST:
delay = 0;
break;
case SENSOR_DELAY_GAME:
delay = 20000;
break;
case SENSOR_DELAY_UI:
delay = 66667;
break;
case SENSOR_DELAY_NORMAL:
delay = 200000;
break;
default:
delay = rate;
break;
}
return delay;
}
SENSOR_DELAY_FASTEST
返回的delay = 0,说明采集的信息立刻返回,非常灵敏,后续的依次减慢,SENSOR_DELAY_NORMAL
是最慢的。
@Override
protected void onResume() {
super.onResume();
sensorManager.registerListener(new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
},accSensor,SensorManager.SENSOR_DELAY_GAME);
}
在注册监听的时候,需要实现SensorEventListener
监听器,当中两个方法:onSensorChanged
和onAccuracyChanged
,分别在数据发生变化时回调,以及精度变化时回调。
在SensorEvent类中,只有这几行代码:
public final float[] values;
/**
* The sensor that generated this event. See
* {@link android.hardware.SensorManager SensorManager} for details.
*/
public Sensor sensor;
/**
* The accuracy of this event. See {@link android.hardware.SensorManager
* SensorManager} for details.
*/
public int accuracy;
/**
* The time in nanosecond at which the event happened
*/
public long timestamp;
@UnsupportedAppUsage
SensorEvent(int valueSize) {
values = new float[valueSize];
}
values数组保存的就是数据的变化值,数组中三个值,分别代表x,y,z三个方向的加速度值。
sensorManager.registerListener(new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
tv_x.setText(Float.toString(values[0]));
tv_y.setText(Float.toString(values[1]));
tv_z.setText(Float.toString(values[2]));
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
},accSensor,SensorManager.SENSOR_DELAY_NORMAL);