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平面中是逆时针方向还是顺时针方向旋转。
光线感应器的硬件位于手机顶部,位于前置摄像头镜头的右侧。