自从苹果公司在2007年发布第一代iPhone以来,曾经看似和手机挨不着边的传感器也逐步成为手机硬件的重要组成部分。假如读者运用过iPhone、HTC Dream、HTC Magic、HTC Hero以及其他的Android手机,会发现经过将手机横向或纵向放置,屏幕会跟着手机方位的不同而改动方向。这种功用就需求经过重力传感器来完成,除了重力传感器,还有许多其他类型的传感器被应用到手机中,例如磁阻传感器便是最重要的一种传感器。尽管手机能够经过GPS来判别方向,但在GPS信号欠好或底子没有GPS信号的情况下,GPS就形同虚设。这时经过磁阻传感器就能够很简单判别方向(东、南、西、北)。有了磁阻传感器,也使罗盘(俗称指向针)的电子化成为可能。
在Android应用程序中运用传感器要依赖于android.hardware.SensorEventListener接口。经过该接口能够监听传感器的各种事情。SensorEventListener接口的代码如下:
package android.hardware;
public interface SensorEventListener
{
public void
onSensorChanged(SensorEvent event);
public void
onAccuracyChanged(Sensor sensor, int accuracy);
}
在SensorEventListener接口中界说了两个办法:onSensorChanged和onAccuracyChanged。当传感器的值发生改动时,例如磁阻传感器的方向改动时会调用onSensorChanged办法。当传感器的精度改动时会调用onAccuracyChanged办法。
onSensorChanged办法只要一个SensorEvent类型的参数event,其间SensorEvent类有一个values变量非常重要,该变量的类型是float[]。但该变量最多只要3个元素,而且依据传感器的不同,values变量中元素所代表的意义也不同。
在解说values变量中元素的意义之前,先来介绍一下Android的坐标体系是怎么界说X、Y、Z轴的。
X轴的方向是沿着屏幕的水平方向从左向右。假如手机不是正方形的话,较短的边需求水平放置,较长的边需求笔直放置。
Y轴的方向是从屏幕的左下角开端沿着屏幕的笔直方向指向屏幕的顶端。
将手机平放在桌子上,Z轴的方向是从手机里指向天空。
下面是values变量的元素在首要的传感器中所代表的意义。
1.1 方向传感器
在方向传感器中values变量的3个值都表明度数,它们的意义如下:
values[0]:该值表明方位,也便是手机绕着Z轴旋转的视点。0表明北(North);90表明东(East);180表明南(South);270表明西(West)。假如values[0]的值正好是这4个值,而且手机是水平放置,表明手机的正前方便是这4个方向。能够运用这个特性来完成电子罗盘,实例76将具体介绍电子罗盘的完成进程。
values[1]:该值表明歪斜度,或手机翘起的程度。当手机绕着X轴歪斜时该值发生改动。values[1]的取值规模是-180≤values[1]
≤180。假定将手机屏幕朝上水平放在桌子上,这时假如桌子是彻底水平的,values[1]的值应该是0(因为很少有桌子是肯定水平的,因而,该值很可能不为0,但一般都是-5和5之间的某个值)。这时从手机顶部开端抬起,直到将手机沿X轴旋转180度(屏幕向下水平放在桌面上)。在这个旋转进程中,values[1]会在0到-180之间改动,也便是说,从手机顶部抬起时,values[1]的值会逐步变小,直到等于-180。假如从手机底部开端抬起,直到将手机沿X轴旋转180度,这时values[1]会在0到180之间改动。也便是values[1]的值会逐步增大,直到等于180。能够运用values[1]和下面要介绍的values[2]来丈量桌子等物体的歪斜度。
values[2]:表明手机沿着Y轴的翻滚视点。取值规模是-90≤values[2]≤90。假定将手机屏幕朝上水平放在桌面上,这时假如桌面是平的,values[2]的值应为0。将手机左边逐步抬起时,values[2]的值逐步变小,直到手机笔直于桌面放置,这时values[2]的值是-90。将手机右侧逐步抬起时,values[2]的值逐步增大,直到手机笔直于桌面放置,这时values[2]的值是90。在笔直方位时持续向右或向左翻滚,values[2]的值会持续在-90至90之间改动。
1.2 加快传感器
该传感器的values变量的3个元素值别离表明X、Y、Z轴的加快值。例如,水平放在桌面上的手机从左边向右侧移动,values[0]为负值;从右向左移动,values[0]为正值。读者能够经过本节的比如来体会加快传感器中的值的改动。要想运用相应的传感器,仅完成SensorEventListener接口是不行的,还需求运用下面的代码来注册相应的传感器。
// 取得传感器管理器
SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
// 注册方向传感器
sm.registerListener(this,
sm.getDefaultSensor(Sensor.TYPE_ORIENTATION),
SensorManager.SENSOR_DELAY_FASTEST);
假如想注册其他的传感器,能够改动getDefaultSensor办法的第1个参数值,例如,注册加快传感器能够运用Sensor.TYPE_ACCELEROMETER。在Sensor类中还界说了许多传感器常量,但要依据手机中实践的硬件装备来注册传感器。假如手机中没有相应的传感器硬件,就算注册了相应的传感器也不起任何效果。getDefaultSensor办法的第2个参数表明取得传感器数据的速度。SensorManager.SENSOR_DELAY_ FASTEST表明尽可能快地取得传感器数据。除了该值以外,还能够设置3个取得传感器数据的速度值,这些值如下:
SensorManager.SENSOR_DELAY_NORMAL:默许的取得传感器数据的速度。
SensorManager.SENSOR_DELAY_GAME:假如运用传感器开发游戏,主张运用该值。
SensorManager.SENSOR_DELAY_UI:假如运用传感器更新UI中的数据,主张运用该值。
1.3 重力感应器
加快度传感器的类型常量是Sensor.TYPE_GRAVITY。重力传感器与加快度传感器运用同一套坐标系。values数组中三个元素别离表明了X、Y、Z轴的重力巨细。Android SDK界说了一些常量,用于表明星系中行星、卫星和太阳外表的重力。下面就来温习一下地理常识,将来假如在地球以外用Android手机,或许会用得上。
public static final float GRAVITY_SUN= 275.0f;
public static final float GRAVITY_MERCURY= 3.70f;
public static final float GRAVITY_VENUS= 8.87f;
public static final float GRAVITY_EARTH= 9.80665f;
public static final float GRAVITY_MOON= 1.6f;
public static final float GRAVITY_MARS= 3.71f;
public static final float GRAVITY_JUPITER= 23.12f;
public static final float GRAVITY_SATURN= 8.96f;
public static final float GRAVITY_URANUS= 8.69f;
public static final float GRAVITY_NEPTUNE= 11.0f;
public static final float GRAVITY_PLUTO= 0.6f;
public static final float GRAVITY_DEATH_STAR_I= 0.000000353036145f;
public static final float GRAVITY_THE_ISLAND= 4.815162342f;1.4 光线传感器
光线传感器的类型常量是Sensor.TYPE_LIGHT。values数组只要第一个元素(values[0])有意义。表明光线的强度。最大的值是120000.0f。Android SDK将光线强度分为不同的等级,每一个等级的最大值由一个常量表明,这些常量都界说在SensorManager类中,代码如下:
public static final float LIGHT_SUNLIGHT_MAX =120000.0f;
public static final float LIGHT_SUNLIGHT=110000.0f;
public static final float LIGHT_SHADE=20000.0f;
public static final float LIGHT_OVERCAST= 10000.0f;
public static final float LIGHT_SUNRISE= 400.0f;
public static final float LIGHT_CLOUDY= 100.0f;
public static final float LIGHT_FULLMOON= 0.25f;
public static final float LIGHT_NO_MOON= 0.001f;
上面的八个常量仅仅临界值。读者在实践运用光线传感器时要依据实践情况确认一个规模。例如,当太阳逐步升起时,values[0]的值很可能会超越LIGHT_SUNRISE,当values[0]的值逐步增大时,就会逐步跳过LIGHT_OVERCAST,而到达LIGHT_SHADE,当然,假如天特别好的话,也可能会到达LIGHT_SUNLIGHT,乃至更高。
1.5 陀螺仪传感器
陀螺仪传感器的类型常量是Sensor.TYPE_GYROSCOPE。values数组的三个元素表明的意义如下:values[0]:延X轴旋转的角速度。
values[1]:延Y轴旋转的角速度。
values[2]:延Z轴旋转的角速度。
当手机逆时针旋转时,角速度为正值,顺时针旋转时,角速度为负值。陀螺仪传感器经常被用来核算手机已滚动的视点,代码如下:
private static final float NS2S = 1.0f / 1000000000.0f;
private float timestamp;
public void onSensorChanged(SensorEvent event)
{
if (timestamp != 0)
{
// event.timesamp表明当时的时刻,单位是纳秒(1百万分之一毫秒)
final float dT = (event.timestamp – timestamp) * NS2S;
angle[0] += event.values[0] * dT;
angle[1] += event.values[1] * dT;
angle[2] += event.values[2] * dT;
}
timestamp = event.timestamp;
}
上面代码中经过陀螺仪传感器相邻两次取得数据的时刻差(dT)来别离核算在这段时刻内手机延X、 Y、Z轴旋转的视点,并将值别离累加到angle数组的不同元素上。
1.6其他传感器
其他传感器在前面几节介绍了加快度传感器、重力传感器、光线传感器、陀螺仪传感器以及方向传感器。除了这些传感器外,Android SDK还支撑如下的几种传感器。关于这些传感器的运用办法以及与这些传感器相关的常量、办法,读者能够参看官方文档。
近程传感器(Sensor.TYPE_PROXIMITY)
线性加快度传感器(Sensor.TYPE_LINEAR_ACCELERATION)
旋转向量传感器(Sensor.TYPE_ROTATION_VECTOR)
磁场传感器(Sensor.TYPE_MAGNETIC_FIELD)
压力传感器(Sensor.TYPE_PRESSURE)
温度传感器(Sensor.TYPE_TEMPERATURE)
尽管AndroidSDK界说了十多种传感器,但并不是每一部手机都彻底支撑这些传感器。例如,Google Nexus S支撑其间的9种传感器(不支撑压力和温度传感器),而HTC G7只支撑其间的5种传感器。假如运用了手机不支撑的传感器,一般不会抛出反常,但也无法取得传感器传回的数据。读者在运用传感器时最好先判别当时的手机是否支撑所运用的传感器。