这篇文章将为读者具体介绍Android中增强实际运用程序的两个要害元素:GPS与加速度传感器。
在前一篇文章《编程完结googleAndroid摄像头摄影》中,咱们介绍了在增强实际技能(AR)引擎中Android SDK的两种根本构件即摄像头的用法。在这篇文章中,咱们将持续介绍别的两种根底构件,即GPS与加速度传感器。咱们首要介绍所需的东西,然后解说怎么恳求方位更新,并阐明加速度传感器的作业机制。
所需东西
下面是这篇文章中将用到的东西:
Android SDK 1.5
T-Mobile G1手机或其模拟器
安装了Android Development Tools (ADT)插件、 NetBeans的Eclipse,或您喜爱的其它集成开发环境
怎么与卫星通信
在完结了Android增强实际引擎的前两个元素即摄像头与指南针之后,下一步要做的即是断定方位。为了完结这项使命,咱们首要用到Android的LocationManager方针。不过在此之前,咱们还需首要处置一些其他疑问,其间权限是咱们首要要打扫的第一个妨碍。
Android的LocationManager撑持两种权限恳求:
1. 需求奉告体系您期望取得用户的方位。
2. 需求通知它您想要非常具体的地理信息。
您需求在AndroidManifest.xmlxml 文件标签内的标签中恳求这两种权限,如下所示:
(uses-permission android:name="android.permission.LOCATION"/ )
关于细粒度的方位更新,也即是近间隔显现有关方针,还需求增加以下内容:
(uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /)
假如没有这两行,当您企图注册方位更新时,Android就将回来一个安全反常,然后致使您的运用封闭。
方位管理器看起来如同挺简略的,可是仍是得紧记一些事项。首要,咱们或许只能在UI主线程中恳求方位管理器。咱们要么在有关动作的onCreate调用中恳求LocationManager方针,要么运用LocationManager恳求创立一个运转于主线程的可执行方针。
获取方位管理器
为简略起见,下面的示例代码将从一个动作的onCreate办法中注册LocationManager更新。
public void onCreate(Bundle savedInstanceState)
{
LocationManager locMan;
locMan =
(LocationManager)getSystemService(Context.LOCATION_SERVICE);
locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER,
100, 1, gpsListener);
}
如您所见,这儿声明晰一个LocationManager方针,运用getSystemService取得您的方针,然后调用了requestLocationUpdates。
您能够想知道方位更新时需求哪些参数。首要,您通知体系,您想运用体系中GPS设备的方位更新功用。然后,您通知它您期望多长时刻更新一次(本例时刻间隔为100ms),而且每逢移动一米以上时就更新。这样,就能敏捷辨认他们的移动状况并调整它们与其他方针的方位联系。最终,传入完结LocationListener接口的类的实例。
方位更新的侦听艺术
为方位更新传递恳求后,LocationListener类将收到初始方位,继之以后来方位的改动状况。下面是咱们的LocationListener:
LocationListener gpsListener = new LocationListener(){
Location curLocation;
boolean locationChanged = false;
public void onLocationChanged(Location location)
{
if(curLocation == null)
{
curLocation = location;
locationChanged = true;
}
if(curLocation.getLatitude() == location.getLatitude() &&
curLocation.getLongitude() == location.getLongitude())
locationChanged = false;
else
locationChanged = true;
curLocation = location;
}
public void onProviderDisabled(String provider){}
public void onProviderEnabled(String provider){}
public void onStatusChanged(String provider, int status, Bundle extras){}
};
在上面的代码中,咱们仅有需求关怀的即是onLocationChanged这个办法。可是,咱们还会介绍这个方针的其它办法,以便您将这个方针仿制到您自个的代码中时能够知道它们。一旦卫星断定了这个设备,办法onLocationChanged就会被调用,之后每经过在恳求更新时指定的时刻间隔(本例中为100ms)后,就会调用一次。
每逢方位更新时,都会带来一个Location方针。咱们经过这个类能够取得方针的经纬度,并完结许多重要作业。这儿咱们最感爱好的办法是getLatitude()、getLongitude()、bearingTo()与distanceTo()。运用这四个函数,咱们能够核算出任何随后的方位的方位角,并断定出离您的间隔有多远。
获取方位管理器
为了完结咱们的增强实际引擎,最终还需求用到加速度传感器数据。不过,Android现已为咱们简化了这些数据的搜集作业。在上一篇介绍增强实际技能的文章中,咱们的示例程序能够恳求手机的方位,并调用方位管理器方针中的registerListener来检索指南针数据。咱们也能够运用相同的技能来恳求加速度传感器数据,咱们用来恳求加速度传感器数据的代码如下所示:
sensorMan = (SensorManager) ctx.getSystemService(Context.SENSOR_SERVICE);
sensorMan.registerListener(listener,
sensorMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_FASTEST);
咱们调用了上下文方针(上述代码中为ctx)的getSystemService办法。下面是用于方向监听器与加速度传感器监听器的完好代码。
private SensorEventListener listener = new SensorEventListener(){
public static volatile float direction = (float) 0;
public static volatile float inclination;
public static volatile float rollingZ = (float)0;
public static volatile float kFilteringFactor = (float)0.05;
public static float aboveOrBelow = (float)0;
public void onAccuracyChanged(Sensor arg0, int arg1){}
public void onSensorChanged(SensorEvent evt)
{
float vals[] = evt.values;
if(evt.sensor.getType() == Sensor.TYPE_ORIENTATION)
{
float rawDirection = vals[0];
direction =(float) ((rawDirection * kFilteringFactor) +
(direction * (1.0 - kFilteringFactor)));
inclination =
(float) ((vals[2] * kFilteringFactor) +
(inclination * (1.0 - kFilteringFactor)));
if(aboveOrBelow > 0)
inclination = inclination * -1;
if(evt.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
{
aboveOrBelow =
(float) ((vals[2] * kFilteringFactor) +
(aboveOrBelow * (1.0 - kFilteringFactor)));
}
}
}
};
这儿的代码略微有点多,下面咱们来知道一下。首要,要为监听器设置一切的值。这意味着,您能够随时能够向监听器查询指南针方位与手机倾角。这些值会跟着您恳求的更新的类型的不一样而有所改变。
然后,咱们会收到传感器信息,这时需求断定出两种首要信息:
1. 手机指向
2. 屏幕相关于水平面的倾角
第一种信息称为方位角;第二种信息称为倾角。为了断定这些值,第一个核算使命即是过滤出摄像头的指南针运动。这称为翻转过滤器(rolling filter)。变量direction用于指出手机顶部指向哪里,而非摄像头自身指向哪里,所以咱们需求进行一些校对。
第二个数学核算使命是使用翻转过滤器对斜度进行处置,然后得到一个以度为单位的度量值,其间水平的度量值为90,向上或向下半倾的度量值为45,笔直向上或笔直向下的度量值为0。注意,当得数为45的时分,咱们无法断定手机到底是向上倾斜,仍是向下倾斜。 这时加速度传感器就派上用场了。它能够断定出倾角的正负,正值表明从水平线向上,仿制表明从水平线向下。
简言之,咱们需求的东西都能从加速度传感器那里得到。
增强实际技能的构件
到目前为止,打造自个增强实际技能引擎所需的东西咱们现已悉数介绍过了,您还需求的即是少量数学知识、一些Android版面规划和很多的精力了。假如您对打造增强实际运用程序的爱好远胜于打造增强实际引擎自身的话,能够重视我当时正在为Android开发的一个开源的增强实际技能引擎。为了取得更多的发展状况,能够在Twitter上跟从twitter.com/androidarkit。
尽管我喜爱尽能够把一切的数学和绘图代码放在一同,并将三种信息统一叠放到摄像头上,可是这些现已超出了这篇文章的评论规模。可是,这篇文章加上上一篇文章,现已构成了对Android的指南针、摄像头预览、加速度传感器与GPS子体系进行了悉数的介绍。如今,您现已具有了创立大型增强实际技能运用程序所需的悉数构件。