200 likes | 291 Views
第九章 Android 位置服务 与地图应用. 本章目标:. 了解位置服务 掌握 Google 地图应用 了解 XML 的解析. 9.1 位置服务.
E N D
本章目标: • 了解位置服务 • 掌握Google地图应用 • 了解XML的解析
9.1 位置服务 • 位置服务(Location Based Services,LBS),又称定位服务或基于位置的服务,融合了GPS定位、移动通信、导航等多种技术,提供了与空间位置相关的综合应用服务。位置服务首先在日本得到商业化的应用。2001年7月,DoCoMo发布了第一款具有三角定位功能的手持设备,2001年12月,KDDI发布第一款具有GPS功能的手机。近些年来,基于位置的服务发展更加迅速,涉及到商务、医疗、工作和生等各个方面,为用户提供定位、追踪和敏感区域警告等一系列服务。 • Android平台支持提供服务的API,在开发过程中主要用到LocationManager和LocationProviders对象。LocationManager可以用来获取当前的位置,追踪设备的移动路线,或设定敏感区域,在进入或者离开敏感区域时设备会发出特定警报。LocationProviders则是能够提供定位功能的组件集合,集合中的每种组件以不同的技术提供设备的当前位置,区别在于定位的精度、速度和成本等方面。
9.1 位置服务 • 为了使开发的程序能够提供位置服务,首先需要获得LocatioManager对象。获取LocatioManager可以通过调用android.app.Activity.getSystemService()函数实现,代码如下: • String serviceString = Context.LOCATION_SERVICE; • LocationManager LocationManager = • (LocationManager)getSystemService(serviceString); • 代码中的Context.LOCATION_SERVICE指明获取的服务是位置服务,getSystemService()函数,可以根据服务名称获取Android提供的系统级服务。
9.1 位置服务 • 在获得LocationManager后,还需要指定LocationManager的定位方法,然后才能够调用LocationManager.getLastKnowLocation()方法获取当前位置。目前LocationManager支持的定位方法有两种,分别是使用GPS定位和使用网络定位。GPS定位可以提供更加精确的位置信息,但定位速度和质量受到卫星数量和环境情况的影响;网络定位提供的位置信息精度较差,但速度较GPS定位快。
9.1 位置服务 • 在指定LocationManager的定位方法后,则可以调用getLastKnowLocation()方法获取当前的位置信息。以使用GPS定位为例,获取位置信息的代码如下: • String provider = LocationManager.GPS_PROVIDER; • Location location = locationManager.getLastKnownLocation(provider); • 代码中返回的Location对象中,包含了可以确定位置的信息,如经度、纬度和速度等,用户可以通过调用Location中的getLatitude()和getLonggitude()方法分别获取位置信息中的纬度和经度,示例代码如下: • double lat = location.getLatitude(); • double lng = location.getLongitude();
9.1 位置服务 • 在很多提供定位服务的应用程序中,不仅需要获取当前的位置信息,还需要监视位置的变化,在位置变化时调用特定的处理方法。LocationManager提供了一种便捷、高效的位置监视方法requestLocationUpdates(),可以根据位置的距离变化和时间间隔设定产生位置改变事件的条件,这样可以避免因微小的距离变化而产生大量的位置改变事件。LocationManaget中设定监听位置变化的代码如下: • locationManager.requestLocationUpdates(provider, 2000, 10, • locationListener); • 方法中的第1个参数是定位的方法,GPS定位或网络定位;第2个参数是产生位置改变事件的时间间隔,单位为微秒;第3个参数是距离条件,单位是米;第4个参数是回调函数,是在满足条件后的位置改变事件的处理函数。上面的代码将产生位置改变事件的条件设定距离改变为10米,时间间隔为2秒。
9.1 位置服务 • 实现locationListener代码如下: • LocationListener locationListener = new LocationListener(){ • public void onLocationChanged(Location location) { } • public void onProviderDisabled(String provider) { } • public void onProviderEnabled(String provider) { } • public void onStatusChanged(String provider, int status, • Bundle extras) { } • }; • 代码中的onLocationChanged()在设备的位置改变时被调用;onProviderDisabled()在用户禁用具有定位功能的硬件时被调用; onProviderEnabled()在用户启用具有定位功能的硬件时被调用; onStatusChanged()在提供定位功能的硬件的状态改变时被调用,如从不可获取位置信息状态到可以获取位置信息的状态,反之亦然。 • 最后,为了使GPS定位功能生效,还需要在AndroidManifest.xml文件中加入用户许可,代码如下: • <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
9.2.1 申请地图密钥 • 为了在手机中更直观地显示地理信息,程序开发人员可以直接使用Google提供的地图服务,实现地理信息的可视化开发。只要使用MapView(com.google.android.maps.MapView)就可以将Google地图嵌入到Android应用程序中。但在使用MapView进行开发前,必须向Google申请一组经过验证的“地图密钥(Map API KEY)”,才能正常使用Google的地图服务。“地图密钥”是访问Google地图数据的密钥,无论是模拟器还是在真实设备中都需要使用这个密钥。 • 注册“地图密钥”的第一步是申请一个Google账户,也就是Gmail电子邮箱,申请地址https://www.google.com/accounts/Login。
9.2.1 申请地图密钥 • 在得到Google账户之后,下一步工作是找到保存Debug证书的keystore的保存位置,并获取证书的MD5散列值。keystore是一个密码保护的文件,用来存储Android提供的用于调试的证书,获取MD5散列值的主要目的是为下一步申请“地图密钥”做准备。获取证书的保存地址如图9-3所示,首先打开Eclipse,通过windows-Preferences打开配置窗体,在Android-Build栏中的Default debug keystore中可以找到。 • 为了获取Debug证书的MD5散列值,需要打开命令行工具CMD,然后切换到keystore的目录,输入如下命令: • keytool –list –keystore debug.keystore • 如果提示无法找到keytool,可以将<Java SDK>/bin的路径添加到系统的PATH变量中。在提示输入keystore密码时,输入默认密码android,MD5散列值将显示在最下方。如图9-4所示,每台电脑的MD5散列值都不一样,这个一定要引起读者注意。笔者的MD5散列值为68:76:89:C8:A4:24:61:F9:EA:F3:F7:70:CC:FD:C8:15。
9.2.1 申请地图密钥 • 申请“地图密钥”的最后一步是打开申请页面,输入MD5散列值。申请页面的地址是: • http://code.google.com/intl/zh-CN/android/google-apis/maps-api-signup.html,
9.2.1 申请地图密钥 • 输入MD5散列值后,单击Generate API Key按钮,将提示用户输入Google账户,正确输入Google账户后,将产生申请“地图密钥”的获取结果,如图9-6所示。
9.2.2 使用Google地图 • 在申请到“地图密钥”后,下面考虑如何在Android系统中显示和控制Google地图。MapView是地图显示控件,可以设置不同显示模式,例如卫星模式、街道模式或交通模式。而MapController则是MapView的控制器,可以控制MapView的显示中心和缩放级别等功能。 • 下面的内容以GoogleMapDemo为例,说明如何在Android系统中开发Google地图程序。这个示例将在程序内部设置一个坐标点,然后在程序启动时你,使用MapView控件在地图上显示这个坐标点的位置。 • 因为普通的Android程序并不包含支持Google地图开发的扩展库,因此应在建立工程时将com.google.android.maps的扩展库添加到工程中,这样就可以使用Google地图的所有功能了,添加com.google.android.maps扩展库的扩展方式是在创建工程时,在Buid Target选项中选择Google APIs
9.2.3 Google地图上贴上标记 • 本节讲一个在Google地图某一个固定的经纬度上贴上相应的标记。在前面的章节中,我们接触了如何与Google地图服务系统的互动,但是我们更希望在地图上贴上自己的标记和注释,这需要可以在地图上覆盖一些对象。要做到这一点,首先要实现一个ItemizedOverlay类,他可以管理一套覆盖项目功能,下面我们通过一个简单的案例来学习这个知识点的应用。 • 建立一个Android项目,名称为HelloMapView。需要的图标拷贝到相应的资源文件内,项目里面包含两个类文件,分别是HelloItemizedOverlay.java和HelloMapView.java。下面对这个项目的完成进行详细的介绍。
9.2.3 Google地图上贴上标记 • 实现一个ItemizedOverlay类程序HelloItemizedOverlay.java需要建立以下四个方法: • public HelloItemizedOverlay(Drawable defaultMarker) • publicvoid addOverlay(OverlayItem overlay) • protected OverlayItem createItem(int i) • publicint size() • 请按下列步骤来实现HelloItemizedOverlay.java程序: • 建立一个新的Android应用程序HelloMapView。并在src文件夹建立Java类HelloItemizedOverlay来实现ItemizedOverlay。 • 2、首先要先建立一个OverlayItem ArrayList数组,这个数组可以放置所有要贴在地图上的标记对象。 • private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
9.2.3 Google地图上贴上标记 • 构造方法会定义每一个被使用OverlayItems的默认标记,为了使Drawable标记可以贴上,必须界定它的范围。地图坐标上的标记希望贴在地图底部的中心点,使用boundCenterBottom()方法来处理,defaultMarker会被super调用。参考代码如下: • super(boundCenterBottom(defaultMarker)); • 为了要增加一个新的OverlayItem 到ArrayList数组上,我们在addOverlay()方法中加入下列代码: • mOverlays.add(overlay); • populate(); • 每一次增加一个新的OverlayItem,一定要调用populate()方法,它会读出每一个OverlayItem并准备它可以被贴上。
9.2.3 Google地图上贴上标记 • 为了读取每一个OverlayItem会调用populate(),必须定义createItem()请求,确认是从ArrayList数组读出。在处理createItem()方法的返回时加入下列代码:return mOverlays.get(i); • 还需要一个覆盖size()方法,在处理size()方法的返回时要加入下列代码: • return mOverlays.size();