《android 移动编程.ppt》由会员分享,可在线阅读,更多相关《android 移动编程.ppt(52页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第第9章章 位置服务与地图位置服务与地图应用应用本章学习目标:n了解位置服务的概念n了解地图密钥的申请方法n掌握获取位置信息的方法n掌握MapView和MapController的使用方法n掌握Google地图覆盖层的使用方法9.1 位置服务 n位置服务q位置服务(Location-BasedServices,LBS),又称定位服务或基于位置的服务,融合了GPS定位、移动通信、导航等多种技术,提供了与空间位置相关的综合应用服务q位置服务首先在日本得到商业化的应用q2001年7月,DoCoMo发布了第一款具有三角定位功能的手持设备q2001年12月,KDDI发布第一款具有GPS功能的手机q基于位
2、置的服务发展迅速,已涉及到商务、医疗、工作和生活的各个方面,为用户提供定位、追踪和敏感区域警告等一系列服务9.1 位置服务 n位置服务qAndroid平台支持提供位置服务的API,在开发过程中主要用到LocationManager和LocationProviders对象qLocationManager可以用来获取当前的位置,追踪设备的移动路线,或设定敏感区域,在进入或离开敏感区域时设备会发出特定警报qLocationProviders是能够提供定位功能的组件集合,集合中的每种组件以不同的技术提供设备的当前位置,区别在于定位的精度、速度和成本等方面9.1 位置服务 n位置服务q提供位置服务,首先
3、需要获得LocationManager对象q获取LocationManager可以通过调用android.app.Activity.getSystemService()函数实现qandroid.app.Activity.getSystemService()函数代码如下n代码第1行的Context.LOCATION_SERVICE指明获取的服务是位置服务n代码第2行的getSystemService()函数,可以根据服务名称获取Android提供的系统级服务1.String serviceString=Context.LOCATION_SERVICE;2.LocationManager Loca
4、tionManager=(LocationManager)getSystemService(serviceString);9.1 位置服务 n位置服务qAndroid支持的系统级服务表ContextContext类的静态常量类的静态常量值值返回对象返回对象说明说明LOCATION_SERVICElocationLocationManager控制位置等设备的更新WINDOW_SERVICEwindowWindowManager最顶层的窗口管理器LAYOUT_INFLATER_SERVICElayout_inflaterLayoutInflater将XML资源实例化为ViewPOWER_SERVI
5、CEpowerPowerManager电源管理ALARM_SERVICEalarmAlarmManager在指定时间接受IntentNOTIFICATION_SERVICEnotificationNotificationManager 后台事件通知KEYGUARD_SERVICEkeyguardKeyguardManager锁定或解锁键盘SEARCH_SERVICEsearchSearchManager访问系统的搜索服务VIBRATOR_SERVICEvibratorVibrator 访问支持振动的硬件CONNECTIVITY_SERVICEconnectionConnectivityMana
6、ger 网络连接管理WIFI_SERVICEwifiWifiManager Wi-Fi连接管理INPUT_METHOD_SERVICEinput_methodInputMethodManager 输入法管理9.1 位置服务 n位置服务q在获取到LocationManager后,还需要指定LocationManager的定位方法,然后才能够调用LocationManagerqgetLastKnowLocation()方法获取当前位置qLocationManager支持的定位方法有两种nGPS定位:可以提供更加精确的位置信息,但定位速度和质量受到卫星数量和环境情况的影响n网络定位:提供的位置信息精
7、度差,但速度较GPS定位快9.1 位置服务 n位置服务qLocationManager支持定位方法q在指定LocationManager的定位方法后,则可以调用getLastKnowLocation()方法获取当前的位置信息LocationManagerLocationManager类类的静态常量的静态常量值值说明说明GPS_PROVIDERgps使用GPS定位,利用卫星提供精确的位置信息,需要android.permissions.ACCESS_FINE_LOCATION用 户权限NETWORK_PROVIDERnetwork使用网络定位,利用基站或Wi-Fi提供近似的位置信息,需要具有如下
8、权限:android.permission.ACCESS_COARSE_LOCATION或android.permission.ACCESS_FINE_LOCATION.9.1 位置服务 n位置服务q以使用GPS定位为例,获取位置信息的代码如下n代码第2行返回的Location对象中,包含了可以确定位置的信息,如经度、纬度和速度等q通过调用Location中的getLatitude()和getLonggitude()方法可以分别获取位置信息中的纬度和经度,示例代码如下1.String provider=LocationManager.GPS_PROVIDER;2.Location locati
9、on=locationManager.getLastKnownLocation(provider);1.double lat=location.getLatitude();2.double lng=location.getLongitude();9.1 位置服务 n位置服务qLocationManager提供了一种便捷、高效的位置监视方法requestLocationUpdates(),可以根据位置的距离变化和时间间隔设定产生位置改变事件的条件,这样可以避免因微小的距离变化而产生大量的位置改变事件qLocationManager中设定监听位置变化的代码如下n第1个参数是定位的方法,GPS定位或
10、网络定位n第2个参数是产生位置改变事件的时间间隔,单位为微秒n第3个参数是距离条件,单位是米n第4个参数是回调函数,在满足条件后的位置改变事件的处理函数locationManager.requestLocationUpdates(provider,2000,10,locationListener);9.1 位置服务 n位置服务n代码将产生位置改变事件的条件设定为距离改变10米,时间间隔为2秒n实现locationListener的代码如下q第2行代码onLocationChanged()在设备的位置改变时被调用1.LocationListener locationListener=new Lo
11、cationListener()2.public void onLocationChanged(Location location)3.4.public void onProviderDisabled(String provider)5.6.public void onProviderEnabled(String provider)7.8.public void onStatusChanged(String provider,int status,Bundle extras)9.10.;9.1 位置服务 n位置服务q第4行的onProviderDisabled()在用户禁用具有定位功能的硬件时
12、被调用q第6行的onProviderEnabled()在用户启用具有定位功能的硬件时被调用q第8行的onStatusChanged()在提供定位功能的硬件的状态改变时被调用,如从不可获取位置信息状态到可以获取位置信息的状态,反之亦然9.1 位置服务 n位置服务q为了使GPS定位功能生效,还需要在AndroidManifest.xml文件中加入用户许可q实现代码如下9.1 位置服务 n位置服务qCurrentLocationDemo是一个提供位置服务的基本示例,提供了显示当前位置新的功能,并能够监视设备的位置变化9.1 位置服务 n位置服务q位置服务一般都需要使用设备上的硬件,最理想的调试方式是
13、将程序上传到物理设备上运行,但在没有物理设备的情况下,也可以使用Android模拟器提供的虚拟方式模拟设备的位置变化,调试具有位置服务的应用程序n首先打开DDMS中的模拟器控制,在LocationControls中的Longitude和Latitude部分输入设备当前的经度和纬度,然后点击Send按钮,就将虚拟的位置信息发送到Android模拟器中9.1 位置服务 n位置服务q在程序运行过程中,可以在模拟器控制器中改变经度和纬度坐标值,程序在检测到位置的变化后,会将最新的位置信息显示在界面上q但笔者在1.5版本的Android模拟器中进行调试时,发现模拟器控制器只能成功的将虚拟坐标发送到模拟器
14、中2次,超过2次后模拟器对新发送的虚拟坐标不再响应9.1 位置服务 n位置服务q下面是CurrentLocationDemo示例中LocationBasedServiceDemo.java文件的完整代码1.package edu.hrbeu.LocationBasedServiceDemo;2.3.import android.app.Activity;4.import android.content.Context;5.import android.os.Bundle;6.import android.widget.TextView;7.import android.location.Loc
15、ation;8.import android.location.LocationListener;9.import android.location.LocationManager;10.9.1 位置服务 n位置服务11.public class LocationBasedServiceDemo extends Activity 12.Override13.public void onCreate(Bundle savedInstanceState)14.super.onCreate(savedInstanceState);15.setContentView(R.layout.main);16
16、.17.String serviceString=Context.LOCATION_SERVICE;18.LocationManager locationManager=(LocationManager)getSystemService(serviceString);19.String provider=LocationManager.GPS_PROVIDER;20.Location location=locationManager.getLastKnownLocation(provider);21.getLocationInfo(location);22.locationManager.re
17、questLocationUpdates(provider,2000,0,locationListener);23.24.9.1 位置服务 n位置服务25.private void getLocationInfo(Location location)26.String latLongInfo;27.TextView locationText=(TextView)findViewById(R.id.txtshow);28.if(location!=null)29.double lat=location.getLatitude();30.double lng=location.getLongitu
18、de();31.latLongInfo=Lat:+lat+nLong:+lng;32.33.else34.latLongInfo=No location found;35.36.locationText.setText(Your Current Position is:n+latLongInfo);37.38.39.private final LocationListener locationListener=new LocationListener()40.Override41.public void onLocationChanged(Location location)42.getLoc
19、ationInfo(location);43.9.1 位置服务 n位置服务44.Override45.public void onProviderDisabled(String provider)46.getLocationInfo(null);47.48.Override49.public void onProviderEnabled(String provider)50.getLocationInfo(null);51.52.Override53.public void onStatusChanged(String provider,int status,Bundle extras)54.
20、55.;56.9.2 Google地图应用n9.2.1申请地图密钥q首先向Google申请一组经过验证的“地图密钥”(MapAPIKey),然后使用MapView(com.google.android.maps.MapView)就可以将Google地图嵌入到Android应用程序中,才能正常使用Google的地图服务q“地图密钥”是访问Google地图数据的密钥,无论是模拟器还是在真实设备中需要使用这个密钥9.2 Google地图应用n9.2.1申请地图密钥q注册“地图密钥”的第一步是申请一个Google账户,也就是Gmail电子邮箱,申请地址是https:/ Google地图应用n9.2.1
21、申请地图密钥n获取证书的保存地址:首先打开Eclipse,通过WindowPreferences打开配置窗体,在AndroidBuild栏中的Defaultdebugkeystore中可以找到9.2 Google地图应用n9.2.1申请地图密钥q为了获取Debug证书MD5散列值的,需要打开命令行工具CMD,然后切换到keystore的目录,输入如下命令q如果提示无法找到keytool,可以将/bin的路径添加到系统的PATH变量中keytool list keystore debug.keystore9.2 Google地图应用n9.2.1申请地图密钥q在提示输入keystore密码时,输入
22、缺省密码android,MD5散列将显示在最下方。笔者的MD5散列值为68:76:89:C8:A4:24:61:F9:EA:F3:F7:70:CC:FD:C8:159.2 Google地图应用n9.2.1申请地图密钥q申请“地图密钥”的最后一步是打开申请页面,输入MD5散列值q申请页面的地址是http:/ Google地图应用n9.2.1申请地图密钥9.2 Google地图应用n9.2.1申请地图密钥q输入MD5散列值后,点击GenerateAPIKey按钮,将提示用户输入Google账户,正确输入Google账户后,将产生申请“地图密钥”的获取结果9.2 Google地图应用n9.2.1申请
23、地图密钥q笔者获取的“地图密钥”是0mVK8GeO6WUz4S2F94z52CIGSSlvlTwnrE4DsiA,在以后使用到MapView的时候都需要输入这个密钥q但需要注意的是,读者并不能使用这个密钥,读者需要根据自己的Debug证书的MD5散列值,重新到Google网站上申请一个用于调试程序的“地图密钥”9.2 Google地图应用n9.2.2使用Google地图qMapView的地图的显示控件,可以设置不同的显示模式,例如卫星模式、街道模式或交通模式qMapController则是MapView的控制器,可以控制MapView的显示中心和缩放级别等功能q下面的内容以GoogleMapD
24、emo为例,说明如何在Android系统中开发Google地图程序q这个示例将在程序内部设置一个坐标点,然后在程序启动时,使用MapView控件在地图上显示这个坐标点的位置9.2 Google地图应用n9.2.2使用Google地图q在建立工程时将com.google.android.maps的扩展库添加到工程中,这样就可以使用Google地图的所有功能q添加com.google.android.maps扩展库的方式是在创建工程时,在BuildTarget项中选择GoogleAPIsq创建工程后,修改/res/layout/main.xml文件,在布局中加入一个MapView控件,并设置刚获取
25、的“地图密钥”9.2 Google地图应用n9.2.2使用Google地图qmain.xml文件的完整代码如下1.2.6.9.10.17.9.2 Google地图应用n9.2.2使用Google地图q仅在布局中添加MapView控件,还不能够直接在程序中调用这个控件,还需要将程序本身设置成MapActivity(com.google.android.maps.MapActivity)qMapActivity类负责处理显示Google地图所需的生命周期和后台服务管理q下面先给出整个GoogleMapDemo.java文件的完整代码1.package edu.hrbeu.GoogleMapDemo
26、;2.3.import com.google.android.maps.GeoPoint;4.import com.google.android.maps.MapActivity;5.import com.google.android.maps.MapController;6.import com.google.android.maps.MapView;7.9.2 Google地图应用n9.2.2使用Google地图8.import android.os.Bundle;9.10.public class GoogleMapDemo extends MapActivity 11.private
27、MapView mapView;12.private MapController mapController;13.14.Override15.public void onCreate(Bundle savedInstanceState)16.super.onCreate(savedInstanceState);17.setContentView(R.layout.main);18.19.mapView=(MapView)findViewById(R.id.mapview);20.mapController=mapView.getController();21.22.Double lng=12
28、6.676530486*1E6;23.Double lat=45.7698895661*1E6;24.GeoPoint point=new GeoPoint(lat.intValue(),lng.intValue();9.2 Google地图应用n9.2.2使用Google地图25.26.mapController.setCenter(point);27.mapController.setZoom(11);28.mapController.animateTo(point);29.30.mapView.setSatellite(false)31.32.33.Override34.protecte
29、d boolean isRouteDisplayed()35./TODO Auto-generated method stub36.return false;37.38.9.2 Google地图应用n9.2.2使用Google地图n第20行代码获取了MapControllern第22行和第23行代码设定的经度为126.676530486*1E6、纬度为45.7698895661*1E6的地理坐标点n第26行代码将这个坐标转化为GeoPoint再使用n第26行代码设置MapView的“显示中点”n第27行代码设置放大层级n在第28行代码将MapView显示区域的中心移动到第26行设置的“显示中心
30、”n第30行代码是设定MapView的地图显示模式是否为卫星模式,设置true则为卫星模式,设置false则为普通模式n第34行代码isRouteDisplayed()方法,是用来统计程序是否显示在Google地图中显示路径信息,默认为不显示9.2 Google地图应用n9.2.2使用Google地图q由于获取Google地图是需要使用互联网的,所以在运行前还需要在AndroidManifest.xml文件中,添加允许访问互联网的许可qAndroidManifest.xml文件的完整代码如下1.2.9.2 Google地图应用n9.2.2使用Google地图6.7.9.10.11.12.13.
31、14.15.16.17.18.19.9.2 Google地图应用n9.2.2使用Google地图q运行结果如图n地图模式n卫星模式9.2 Google地图应用n9.2.3使用Overlayq通过在MapView上添加覆盖层,可以在指定的位置加添加注解、绘制图像或处理进行鼠标事件等qGoogle地图上可以加入多个覆盖层,所有覆盖层均都在地图图层之上,每个覆盖层均可以对用户的点击事件做出响应q创建覆盖层继承Overlay类的子类,并通过重载draw()方法为指定位置添加注解,重载onTap()方法处理用户的点击操作9.2 Google地图应用n9.2.3使用Overlayq下面的代码是创建Over
32、lay的最小代码集合1.public class TextOverlay extends Overlay 2.Override3.public void draw(Canvas canvas,MapView mapView,boolean shadow)4.if(shadow=false)5.6.7.else8.9.super.draw(canvas,mapView,shadow);10.11.12.Override13.public boolean onTap(GeoPoint p,MapView mapView)14.return false;15.16.9.2 Google地图应用n9.
33、2.3使用Overlayn第3行代码中draw()方法,shadow变量是用来区分绘制图层的qfalse表示在覆盖层上进行绘制qtrue则表示在隐藏层上进行绘制n第14行代码是onTap()方法的返回值q返回false表示覆盖层不处理点击事件q返回true则表示已经处理了点击事件q在覆盖层绘制图形或文字需要使用“画布”(Canvas)来实现,绘制的位置是屏幕坐标,这就需要将地图上的物理坐标与屏幕坐标进行转换9.2 Google地图应用n9.2.3使用OverlayqProjection类提供了物理坐标和屏幕坐标的转换功能,可在经度和纬度表示的GeoPoint点和屏幕上Point点进行转换nto
34、Pixels()方法将物理坐标转换为屏幕坐标nfromPixels()方法将屏幕坐标转换为物理坐标q两个方法的具体使用方法可以参考下面的代码1.Projection projection=mapView.getProjection();2.3.projection.toPixels(geoPoint,point);4.projection.fromPixels(point.x,point.y);9.2 Google地图应用n9.2.3使用Overlayq下面的内容以MapOverlayDemo示例,说明如何在Google地图上添加覆盖层,并在预订的物理坐标上显示提示信息q右图是MapOverl
35、ayDemo示例的运行结果9.2 Google地图应用n9.2.3使用OverlayqTextOverlay类是MapOverlayDemo示例的覆盖层,主要重载了draw()方法,在指定的物理坐标上绘制了标记点和提示文字qTextOverlay.java文件的核心代码如下1.public class TextOverlay extends Overlay 2.private final int mRadius=5;3.4.Override5.public void draw(Canvas canvas,MapView mapView,boolean shadow)6.Projection p
36、rojection=mapView.getProjection();7.9.2 Google地图应用n9.2.3使用Overlay8.if(shadow=false)9.Double lng=126.676530486*1E6;10.Double lat=45.7698895661*1E6;11.GeoPoint geoPoint=new GeoPoint(lat.intValue(),lng.intValue();12.13.Point point=new Point();14.projection.toPixels(geoPoint,point);15.16.RectF oval=new
37、RectF(point.x-mRadius,point.y-mRadius,point.x+mRadius,point.y+mRadius);17.18.Paint paint=new Paint();19.paint.setARGB(250,250,0,0);20.paint.setAntiAlias(true);21.paint.setFakeBoldText(true);22.9.2 Google地图应用n9.2.3使用Overlayn第2行代码定义了绘制半径变量mRadius,供定义绘制范围使用n第14行代码使用Projection完成了从物理坐标到屏幕坐标的转换23.canvas.d
38、rawOval(oval,paint);24.canvas.drawText(标记点,point.x+2*mRadius,point.y,paint);25.26.super.draw(canvas,mapView,shadow);27.28.29.Override30.public boolean onTap(GeoPoint p,MapView mapView)31.return false;32.33.9.2 Google地图应用n9.2.3使用Overlayn第16行代码oval设定标记点的大小n第19行设置了绘制颜色n第20行开启了平滑设置,防止文字出现锯齿n第23行代码绘制了圆形的
39、标记点n第24行代码绘制了提示文字,第2个和第3个参数是绘制屏幕的x坐标和y坐标9.2 Google地图应用n9.2.3使用Overlayq建立了覆盖层后,还需要把覆盖层添加到MapView上qMapOverlayDemo.java的核心代码如下1.public class MapOverlayDemo extends MapActivity 2.private MapView mapView;3.private MapController mapController;4.private TextOverlay textOverlay;5.6.Override7.public void onC
40、reate(Bundle savedInstanceState)8.super.onCreate(savedInstanceState);9.setContentView(R.layout.main);10.10.11.11.mapView=(MapView)findViewById(R.id.mapview);12.mapController=mapView.getController();13.9.2 Google地图应用n9.2.3使用Overlay14.Double lng=126.676530486*1E6;15.Double lat=45.7698895661*1E6;16.Geo
41、Point point=new GeoPoint(lat.intValue(),lng.intValue();17.18.mapController.setCenter(point);19.mapController.setZoom(11);20.mapController.animateTo(point);21.22.textOverlay=new TextOverlay();23.List overlays=mapView.getOverlays();24.overlays.add(textOverlay);25.26.27.Override28.protected boolean isRouteDisplayed()29.return false;30.31.9.2 Google地图应用n9.2.3使用Overlayn第22行代码实例化了TextOverlay对象n第23行代码通过getOverlays()方法,获取MapView已有的覆盖层n第24行代码使用add()方法将TextOverlay对象对象添加到MapView中习题:n1.讨论位置服务和地图应用的发展前景。n2.编程实现轨迹追踪软件。每间隔60秒,同时距离移动大于1米的情况下,记录一次位置信息,在Google地图上绘制600秒的行动轨迹。
限制150内