官方API:
https://developer.android.com/guide/topics/sensors/sensors_overview
1.项目设置
如果您的应用程序在不需要所有硬件传感器的设备上无法使用,则不能在此类设备上安装。您可以通过在<uses-feature>
Android Studio项目的清单文件中添加一个或多个标签来让Google Play和其他应用程式市场了解应用程式的硬体要求。
我们将在本教程中创建的应用程序将不适用于缺少接近传感器和陀螺仪的设备。因此,将以下行添加到清单文件中:
1
2
3
4
五
6
|
< uses-feature
android:name = "android.hardware.sensor.proximity"
android:required = "true" />
< uses-feature
android:name = "android.hardware.sensor.gyroscope"
android:required = "true" />
|
但是请注意,<uses-feature>
如果用户使用其APK文件手动安装应用程序,则该标签无法帮助,则在使用传感器之前,仍必须以编程方式检查传感器是否可用。
2.使用接近传感器
为了避免意外的触摸事件,您的手机的触摸屏在通话期间会变黑,当它非常接近您的耳朵时。曾经想过你的手机如何确定它是否接近你的耳朵?那么它使用接近传感器,这是一个硬件传感器,可以判断物体是否接近它。一些接近传感器也可以告诉物体有多远,尽管它们的最大范围通常只有约5厘米。
现在让我们创建一个活动,其背景颜色在每次将您的手悬停在设备的接近传感器上时变为红色。
步骤1:获取接近传感器
要访问任何硬件传感器,您需要一个SensorManager
对象。要创建它,请使用getSystemService()
您的Activity
类的方法并将SENSOR_SERVICE
常量传递给它。
// 取传感器 sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
|
您现在可以Sensor
通过调用该getDefaultSensor()
方法并将TYPE_PROXIMITY
常量传递给它来为接近传感器创建一个对象。
1
2
|
proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
|
在继续之前,始终确保Sensor
对象不是null
。如果是,则表示接近传感器不可用。
1
2
3
4
|
if (proximitySensor == null) { Toast.makeText(this, "接近传感器不可用", Toast.LENGTH_LONG).show(); finish(); // Close app }
|
步骤2:注册听众
为了能够读取传感器生成的原始数据,您必须SensorEventListener
通过调用对象的registerListener()
方法来与它相关联SensorManager
。在执行此操作时,您还必须指定从传感器读取数据的频率。
以下代码注册一个监听器,您可以每两秒读取一次接近传感器的数据:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
// Create listener 创建监听器 proximitySensorListener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent sensorEvent) { // More code goes here if(sensorEvent.values[0] < proximitySensor.getMaximumRange()) { // Detected something nearby 检测到附近的东西 getWindow().getDecorView().setBackgroundColor(Color.RED); } else { // Nothing is nearby 附近没什么 getWindow().getDecorView().setBackgroundColor(Color.GREEN); } } @Override public void onAccuracyChanged(Sensor sensor, int i) { } }; // Register it, specifying the polling interval in 注册,指定轮询间隔 // microseconds 微秒 sensorManager.registerListener(proximitySensorListener, proximitySensor, 2 * 1000 * 1000);
|
我建议您始终在onResume()
活动的方法内注册该监听器,并在方法内取消注册onPause()
。以下是注销侦听器的方法:
1 |
sensorManager.unregisterListener(proximitySensorListener); |
步骤3:使用原始数据
该SensorEvent
方法中可用的对象onSensorChanged()
具有包含values
相关传感器生成的所有原始数据的数组。在接近传感器的情况下,阵列包含指定传感器和附近物体之间距离(厘米)的单个值。
如果该值等于传感器的最大范围,则可以安全地假定附近没有。相反,如果它小于最大范围,则意味着附近有些东西。您可以使用getMaximumRange()
相关Sensor
对象的方法确定任何硬件传感器的最大范围。
要根据接近传感器的数据实际更改活动的背景颜色,可以使用setBackgroundColor()
*窗口的装饰视图的方法。
因此,onSensorChanged()
在上一步中创建的方法中添加以下代码:
1
2
3
4
五
6
7
|
// More code goes here if(sensorEvent.values[0] < proximitySensor.getMaximumRange()) { // Detected something nearby 检测到附近的东西 getWindow().getDecorView().setBackgroundColor(Color.RED); } else { // Nothing is nearby 附近没什么 getWindow().getDecorView().setBackgroundColor(Color.GREEN); }
|
如果您现在运行该应用程序并将手悬停在手机的顶部边缘,则应该会看到屏幕变红。
3.使用陀螺仪
陀螺仪允许您在任何给定时刻确定Android设备的角速度。简单来说,它告诉您设备绕X,Y和Z轴旋转的速度有多快。最近,即使是预算手机正在制造,陀螺仪内置,增强现实和虚拟现实应用程序变得如此受欢迎。
通过使用陀螺仪,您可以开发可以响应设备方向的微小更改的应用程序。要了解如何,现在让我们创建一个活动,其背景颜色每次沿Z轴沿逆时针方向旋转手机时,蓝色变为蓝色,否则为黄色。
步骤1:获取陀螺仪
要创建Sensor
陀螺仪的对象,所有您需要做的是将TYPE_GYROSCOPE
常量传递给对象的getDefaultSensor()
方法SensorManager
。
1
2
|
// 获取陀螺仪 gyroscopeSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
|
步骤2:注册听众
创建陀螺仪传感器的监听器与为接近传感器创建侦听器没有什么不同。但是,注册时,您必须确保其采样频率非常高。因此,我建议您使用SENSOR_DELAY_NORMAL
常量,而不是以微秒为单位指定轮询间隔。
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
// Create a listener gyroscopeSensorListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
// More code goes here
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
};
// Register the listener 注册听众 sensorManager.registerListener(gyroscopeSensorListener, gyroscopeSensor, SensorManager.SENSOR_DELAY_NORMAL);
|
步骤3:使用原始数据
陀螺传感器的原始数据由三个float
值组成 ,指定器件沿X,Y和Z轴的角速度。每个值的单位是每秒弧度。在沿着任何轴的逆时针旋转的情况下,与该轴相关联的值将为正。在顺时针旋转的情况下,它将为负。
因为我们目前只对沿着Z轴的旋转感兴趣,所以我们将只使用对象values
数组中的第三个元素SensorEvent
。如果超过0.5f
,我们可以在很大程度上确保旋转是逆时针旋转的,并将背景颜色设置为蓝色。类似地,如果它小于-0.5f
,我们可以将背景颜色设置为黄色。
1
2
3
4
五
|
// More code goes here if (sensorEvent.values[2] > 0.5f) { // anticlockwise getWindow().getDecorView().setBackgroundColor(Color.BLUE); } else if (sensorEvent.values[2] < -0.5f) { // clockwise getWindow().getDecorView().setBackgroundColor(Color.YELLOW); }
|
如果您现在运行该应用程序,请将手机置于纵向模式,然后将其向左倾斜,您应该看到活动变为蓝色。如果倾斜方向相反,则应变黄。
但是,如果您将手机转到太多,屏幕方向将变为横向,您的活动将重新启动。为了避免这种情况,我建议您在清单文件中设置screenOrientation
活动portrait
。
1
2
3
4
|
<activity android:name= ".GyroscopeActivity"
android:screenOrientation= "portrait" >
</activity> |
4.使用旋转矢量传感器
大多数开发者今天都喜欢软件,复合传感器超过硬件传感器 软件传感器结合了来自多个硬件传感器的低级原始数据,生成不仅易于使用的新数据,而且更准确。接近传感器没有替代软件。然而,陀螺仪具有两个:游戏旋转矢量传感器和旋转矢量传感器。在本教程中,我们将仅关注后者。
在上一步的例子中,我们每次沿着Z轴的角速度顺时针或逆时针方向大于0.5rad / s时,改变了活动的背景颜色。然而,使用角速度并不直观。此外,我们不知道设备在旋转之前或之后的实际角度。
通过使用旋转矢量传感器,让我们现在创建一个活动,其背景颜色只有在旋转了特定角度时才会改变。例如,我们可以将其沿着Z轴的旋转度大于45°时变为黄色,当其旋转在-10°和10°之间时为白色,当旋转小于-45°时,它们为蓝色。
步骤1:设置旋转矢量传感器
要获取旋转矢量传感器,必须将TYPE_ROTATION_VECTOR
常量传递给对象的getDefaultSensor()
方法SensorManager
。
1
2
|
// 获取旋转矢量传感器 rotationVectorSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
|
使用软件传感器与使用硬件传感器没有什么不同。因此,您必须将侦听器与旋转矢量传感器相关联才能读取其数据。您可以再次使用SENSOR_DELAY_NORMAL
常量进行轮询间隔。
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
// Create a listener rvListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
// More code goes here
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
}; // Register it sensorManager.registerListener(rvListener, rotationVectorSensor, SensorManager.SENSOR_DELAY_NORMAL); |
步骤2:使用数据
旋转矢量传感器组合由陀螺仪,加速度计和磁力计产生的原始数据,以产生四元数。因此,values
其SensorEvent
对象的数组有以下五个元素:
-
四元数的X,Y,Z和W分量
-
标题精度
您可以通过使用该类的getRotationMatrixFromVector()
方法将四元数转换为旋转矩阵,即4x4矩阵SensorManager
。
1
2
3
|
float[] rotationMatrix = new float[16]; SensorManager.getRotationMatrixFromVector( rotationMatrix, sensorEvent.values);
|
如果您正在开发OpenGL应用程序,则可以直接使用旋转矩阵来转换3D场景中的对象。然而,现在,我们将旋转矩阵转换成方向阵列,指定器件沿着Z,X和Y轴的旋转。为此,我们可以使用该类的getOrientation()
方法SensorManager
。
在调用该getOrientation()
方法之前,必须重新映射旋转矩阵的坐标系。更准确地说,您必须旋转旋转矩阵,使新坐标系的Z轴与原始坐标系的Y轴重合。
01
02
03
04
05
06
07
08
09
10
|
// Remap coordinate system float[] remappedRotationMatrix = new float[16]; SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, remappedRotationMatrix); // Convert to orientations float[] orientations = new float[3]; SensorManager.getOrientation(remappedRotationMatrix, orientations);
|
默认情况下,orientations
数组包含弧度而不是度数的角度。如果您习惯于弧度,请直接使用它。否则,使用以下代码将其所有角度转换为度数:
1
2
3
|
for(int i = 0; i < 3; i++) { orientations[i] = (float)(Math.toDegrees(orientations[i])); }
|
您现在可以根据orientations
数组的第三个元素更改活动的背景颜色。
1
2
3
4
五
6
7
|
if(orientations[2] > 45) { getWindow().getDecorView().setBackgroundColor(Color.YELLOW); } else if(orientations[2] < -45) { getWindow().getDecorView().setBackgroundColor(Color.BLUE); } else if(Math.abs(orientations[2]) < 10) { getWindow().getDecorView().setBackgroundColor(Color.WHITE); }
|
如果您现在运行该应用程序,请将手机置于肖像模式,并顺时针或逆时针倾斜45度以上,您应该会看到背景颜色的变化。