Android传感器
在本教程中,我们将深入研究Android传感器的世界。
我们的智能手机不仅限于速度,UI和动画。
Android传感器
Android Sensors包含可检测环境变化的属性,例如光线,接近度,旋转,运动,磁场等。
从广义上讲,Android传感器属于以下类别:
- 环境传感器
- 运动传感器
- 方向和位置传感器
要访问Android中的各种Sensor,必须使用SensorManager类。
以下代码显示了如何初始化SensorManager:
SensorManager sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
接下来,您可以使用Sensor类来实例化特定的Sensor。
Sensor lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
接下来,您可以使用以下代码注册传感器:
sensorManager.registerListener(this, lightSensor,
SensorManager.SENSOR_DELAY_NORMAL);
建议您在onResume()方法中注册侦听器,并在onPause方法中取消注册侦听器,以节省电池电量。
为了监听传感器事件,您可以在活动中实现SensorEventListener接口。
您需要为此重写以下方法:
@Override
public void onSensorChanged(SensorEvent event) {
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
要获取设备上所有可用传感器的列表,请使用以下代码:
List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL);
String sensorInfo = "";
for (Sensor s : sensorList){
sensorInfo= sensorInfo + s.getName()+ "\n";
}
在下一节中,我们将讨论一些常见的传感器类型。
Android传感器类型
光度计用于感应和控制亮度。
此外,还有压力,湿度和温度传感器。对于运动,加速度计用于检测摇动/倾斜手势。
接近传感器用于检测物体与设备的距离。
它通常出现在"呼叫应用程序"中。
当您将手机靠近耳朵时,借助此传感器,屏幕会变黑。
虽然最大接近范围是5厘米。陀螺仪用于测量旋转/自旋。
重力传感器用于测量重力。磁力仪用于获取设备位置。
计步器用于检测用户执行的步数。
下图描绘了几种传感器类型及其事件数据值以及相应的格式。
如何检查Android Sensor是否可用?
某些设备不支持某些传感器。
因此,您只需在列表文件中添加权限。
Google确保Play商店中的应用程序对于不支持设备的用户不可见。
<uses-feature android:name="android.hardware.accelerometer" android:required="true" <uses-feature android:name="android.hardware.sensor.proximity" android:required="true" <uses-feature android:name="android.hardware.sensor.gyroscope" android:required="true"
加速度计在Android模拟器上不可用。
在下一节中,我们将在Android应用程序中实现某些传感器。
Android传感器示例代码
下面给出了" activity_main.xml"的代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="16dp"
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/btnAccelerometer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="accelerometerSensorOnClick"
android:text="Accelerometer"
<Button
android:id="@+id/btnProximity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="proximitySensorOnClick"
android:text="Proximity Sensor"
<Button
android:id="@+id/btnGyro"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="gyroscopeSensorOnClick"
android:text="Gyroscope"
<Button
android:id="@+id/btnLightSensor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="lightSensorOnClick"
android:text="Light Sensor"
<Button
android:id="@+id/btnStepCounterOnClick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="stepCounterOnClick"
android:text="Step Counter Sensor"
<Button
android:id="@+id/btnAmbientTemp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="ambientTempSensorOnClick"
android:text="Ambient Temperature Sensor"
<TextView
android:id="@+id/tvResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Values would be entered here..."
</LinearLayout>
MainActivity.java的代码如下:
package com.theitroad.androidsensors;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private TextView textView;
private SensorManager sensorManager;
private Sensor accelerometerSensor;
private Sensor proximitySensor;
private Sensor lightSensor;
private Sensor stepCounterSensor;
private Sensor tempSensor;
private Sensor gyroscopeSensor;
private int currentSensor;
private long lastUpdate = 0;
private float last_x, last_y, last_z;
private static final int SHAKE_THRESHOLD = 600;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.tvResult);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
stepCounterSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
gyroscopeSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
tempSensor = sensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE);
}
public boolean checkSensorAvailability(int sensorType) {
boolean isSensor = false;
if (sensorManager.getDefaultSensor(sensorType) != null) {
isSensor = true;
}
return isSensor;
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == currentSensor) {
if (currentSensor == Sensor.TYPE_LIGHT) {
float valueZ = event.values[0];
textView.setText("Brightness " + valueZ);
} else if (currentSensor == Sensor.TYPE_PROXIMITY) {
float distance = event.values[0];
textView.setText("Proximity " + distance);
} else if (currentSensor == Sensor.TYPE_STEP_DETECTOR) {
float steps = event.values[0];
textView.setText("Steps : " + steps);
} else if (currentSensor == Sensor.TYPE_ACCELEROMETER) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
long curTime = System.currentTimeMillis();
if ((curTime - lastUpdate) > 100) {
long diffTime = (curTime - lastUpdate);
lastUpdate = curTime;
float speed = Math.abs(x + y + z - last_x - last_y - last_z)/diffTime * 10000;
if (speed > SHAKE_THRESHOLD) {
Toast.makeText(getApplicationContext(), "Your phone just shook", Toast.LENGTH_LONG).show();
}
last_x = x;
last_y = y;
last_z = z;
}
} else if (currentSensor == Sensor.TYPE_GYROSCOPE) {
if (event.values[2] > 0.5f) {
textView.setText("Anti Clock");
} else if (event.values[2] < -0.5f) {
textView.setText("Clock");
}
} else if (currentSensor == Sensor.TYPE_AMBIENT_TEMPERATURE) {
textView.setText("Ambient Temp in Celsius :" + event.values[0]);
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void accelerometerSensorOnClick(View view) {
if (checkSensorAvailability(Sensor.TYPE_ACCELEROMETER)) {
currentSensor = Sensor.TYPE_ACCELEROMETER;
}
textView.setText("Accelerometer not available");
}
public void proximitySensorOnClick(View view) {
if (checkSensorAvailability(Sensor.TYPE_PROXIMITY)) {
currentSensor = Sensor.TYPE_PROXIMITY;
}
textView.setText("Proximity Sensor not available");
}
public void gyroscopeSensorOnClick(View view) {
if (checkSensorAvailability(Sensor.TYPE_GYROSCOPE)) {
currentSensor = Sensor.TYPE_GYROSCOPE;
} else {
textView.setText("Gyroscope Sensor not available");
}
}
public void lightSensorOnClick(View view) {
if (checkSensorAvailability(Sensor.TYPE_LIGHT)) {
currentSensor = Sensor.TYPE_LIGHT;
} else {
textView.setText("Light Sensor not available");
}
}
public void stepCounterOnClick(View view) {
if (checkSensorAvailability(Sensor.TYPE_STEP_DETECTOR)) {
currentSensor = Sensor.TYPE_STEP_DETECTOR;
} else {
textView.setText("Step Counter Sensor not available");
}
}
public void ambientTempSensorOnClick(View view) {
if (checkSensorAvailability(Sensor.TYPE_AMBIENT_TEMPERATURE)) {
currentSensor = Sensor.TYPE_AMBIENT_TEMPERATURE;
} else {
textView.setText("Ambient Temperature Sensor not available");
}
}
@Override
protected void onResume() {
super.onResume();
sensorManager.registerListener(this, accelerometerSensor,
SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(this, lightSensor,
SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(this, proximitySensor,
SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(this, stepCounterSensor,
SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(this, tempSensor,
SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(this, gyroscopeSensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
}
对于加速度计,我们需要从三个轴中的每个轴获取所有三个坐标的位置。
加速度计非常灵敏,因此会不断更新这些点。
为了检测是否晃动,我们采用给定时间范围内的点差来检测它们移动的速度。
陀螺仪检测手机在z平面中是逆时针方向还是顺时针方向旋转。
光线感应器的硬件位于手机顶部,位于前置摄像头镜头的右侧。

