为什么总是期望用户点击触摸屏上的按钮?通过使用中端Android手机上可用的一些硬件传感器,您可以创建提供更加吸引人的用户体验的应用程序。
传感器框架是Android SDK的一部分,它允许您以简单和一致的方式从大多数传感器(无论是硬件还是软件)读取原始数据。在本教程中,我将向您展示如何使用框架从两个非常常见的传感器读取数据:接近和陀螺仪。我还将向您介绍旋转矢量传感器,一种复合传感器,在大多数情况下,它可以作为陀螺仪更简单,更准确的替代方案。
您可以阅读以下教程,了解Android的硬件传感器:
ANDROID SDK Android从头开始:硬件传感器 保罗Trebilcox-Ruiz要跟随,您将需要以下内容:
具有接近传感器和陀螺仪的Android设备 最新版本的Android Studio如果您的应用程序在不需要所有硬件传感器的设备上无法使用,则不能在此类设备上安装。您可以通过在<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文件手动安装应用程序,则该标签无法帮助,则在使用传感器之前,仍必须以编程方式检查传感器是否可用。
为了避免意外的触摸事件,您的手机的触摸屏在通话期间会变黑,当它非常接近您的耳朵时。曾经想过你的手机如何确定它是否接近你的耳朵?那么它使用接近传感器,这是一个硬件传感器,可以判断物体是否接近它。一些接近传感器也可以告诉物体有多远,尽管它们的最大范围通常只有约5厘米。
现在让我们创建一个活动,其背景颜色在每次将您的手悬停在设备的接近传感器上时变为红色。
要访问任何硬件传感器,您需要一个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 }为了能够读取传感器生成的原始数据,您必须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);该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); }如果您现在运行该应用程序并将手悬停在手机的顶部边缘,则应该会看到屏幕变红。
陀螺仪允许您在任何给定时刻确定Android设备的角速度。简单来说,它告诉您设备绕X,Y和Z轴旋转的速度有多快。最近,即使是预算手机正在制造,陀螺仪内置,增强现实和虚拟现实应用程序变得如此受欢迎。
通过使用陀螺仪,您可以开发可以响应设备方向的微小更改的应用程序。要了解如何,现在让我们创建一个活动,其背景颜色每次沿Z轴沿逆时针方向旋转手机时,蓝色变为蓝色,否则为黄色。
要创建Sensor陀螺仪的对象,所有您需要做的是将TYPE_GYROSCOPE常量传递给对象的getDefaultSensor()方法SensorManager。
1 2 // 获取陀螺仪 gyroscopeSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);创建陀螺仪传感器的监听器与为接近传感器创建侦听器没有什么不同。但是,注册时,您必须确保其采样频率非常高。因此,我建议您使用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);陀螺传感器的原始数据由三个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>大多数开发者今天都喜欢软件,复合传感器超过硬件传感器 软件传感器结合了来自多个硬件传感器的低级原始数据,生成不仅易于使用的新数据,而且更准确。接近传感器没有替代软件。然而,陀螺仪具有两个:游戏旋转矢量传感器和旋转矢量传感器。在本教程中,我们将仅关注后者。
在上一步的例子中,我们每次沿着Z轴的角速度顺时针或逆时针方向大于0.5rad / s时,改变了活动的背景颜色。然而,使用角速度并不直观。此外,我们不知道设备在旋转之前或之后的实际角度。
通过使用旋转矢量传感器,让我们现在创建一个活动,其背景颜色只有在旋转了特定角度时才会改变。例如,我们可以将其沿着Z轴的旋转度大于45°时变为黄色,当其旋转在-10°和10°之间时为白色,当旋转小于-45°时,它们为蓝色。
要获取旋转矢量传感器,必须将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度以上,您应该会看到背景颜色的变化。
在本教程中,您学习了如何使用Android的传感器框架来创建可以响应接近传感器和陀螺仪生成的数据的应用程序。您还学习了如何使用旋转矢量传感器,这是陀螺仪更受欢迎的替代品。随意使用传感器的创意方式。请注意,使用低效传感器的应用程序可能会很快耗尽设备的电池。
要了解有关硬件传感器及其生成的数据的更多信息,可参考官方传感器API指南。并在Envato Tuts +上查看我们的其他硬件和传感器内容!
原文地址 传送门
无意中看到这篇文章 感觉很有意思 就学习了下 三种传感器我都集成在了一起 测试的时候最好注释掉其他两个 要不会混乱 整个屏幕 五颜六色跳动个不停 源码我注释掉了其他两个 只留下了距离传感器 其他两个自行放开
源码