在android开发中地图和定位是很多软件不可或缺的内容,这些特色功能也给人们带来了很多方便。
首先介绍一下地图包中的主要类:
MapController : 主要控制地图移动,伸缩,以某个GPS坐标为中心,控制MapView中的view组件,管理Overlay,提供View的基本功能。使用多种地图模式(地图模式(某些城市可实时对交通状况进行更新),卫星模式,街景模式)来查看Google Map。常用方法:animateTo(GeoPoint point) setCenter(GeoPoint point) setZoom(int zoomLevel) 等。
Mapview : 是用来显示地图的view, 它派生自android.view.ViewGroup。当MapView获得焦点,可以控制地图的移动和缩放。地图可以以不同的形式来显示出来,如街景模式,卫星模式等,通过setSatellite(boolean) setTraffic(boolean), setStreetView(boolean) 方法。
Overlay : 是覆盖到MapView的最上层,可以扩展其ondraw接口,自定义在MapView中显示一些自己的东西。MapView通过MapView.getOverlays()对Overlay进行管理。
Projection :MapView中GPS坐标与设备坐标的转换(GeoPoint和Point)。
定位系统包中的主要类:
LocationManager:本类提供访问定位服务的功能,也提供获取最佳定位提供者的功能。另外,临近警报功能也可以借助该类来实现。
LocationProvider:该类是定位提供者的抽象类。定位提供者具备周期性报告设备地理位置的功能。
LocationListener:提供定位信息发生改变时的回调功能。必须事先在定位管理器中注册监听器对象。
Criteria:该类使得应用能够通过在LocationProvider中设置的属性来选择合适的定位提供者。
Geocoder:用于处理地理编码和反向地理编码的类。地理编码是指将地址或其他描述转变为经度和纬度,反向地理编码则是将经度和纬度转变为地址或描述语言,其中包含了两个构造函数,需要传入经度和纬度的坐标。getFromLocation方法可以得到一组关于地址的数组。
下面开始地图定位实例的开发,在开发地图前需要 获取Android地图 API密钥 网上有很多资料,这里就不再复述。
首先要在manifest.xml中设置全相应的权限和maps库:
02 |
android:icon = "@drawable/ic_launcher" |
03 |
android:label = "@string/app_name" > |
05 |
android:label = "@string/app_name" |
06 |
android:name = ".MyMapActivity" > |
08 |
< action android:name = "android.intent.action.MAIN" /> |
10 |
< category android:name = "android.intent.category.LAUNCHER" /> |
13 |
< span style = "color:#FF6666;" > |
14 |
< uses-library android:name = "com.google.android.maps" /></ span > |
17 |
< span style = "color:#FF6666;" > < uses-permission android:name = "android.permission.INTERNET" /> |
18 |
< uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION" /> |
19 |
< uses-permission android:name = "android.permission.ACCESS_COARSE_LOCATION" /></ span > |
在上面我标红的千万不要忘记。
layout下的main.xml:
01 |
<? xml version = "1.0" encoding = "utf-8" ?> |
02 |
< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" |
03 |
android:layout_width = "fill_parent" |
04 |
android:layout_height = "fill_parent" |
05 |
android:orientation = "vertical" > |
07 |
< com.google.android.maps.MapView |
08 |
android:id = "@+id/mapview" |
09 |
android:layout_width = "fill_parent" |
10 |
android:layout_height = "fill_parent" |
11 |
android:apiKey = "008uu0x2a7GWlK2LzCW872afBAPLhJ-U2R26Wgw" |
下面是核心代码,重要的地方我做了注释:
001 |
public class MyMapActivity extends MapActivity { |
002 |
/** Called when the activity is first created. */ |
003 |
private MapController mapController; |
004 |
private MapView mapView; |
005 |
private MyOverLay myOverLay; |
008 |
public void onCreate(Bundle savedInstanceState) { |
009 |
super .onCreate(savedInstanceState); |
010 |
setContentView(R.layout.main); |
012 |
LocationManager locationManager=(LocationManager) getSystemService(Context.LOCATION_SERVICE); |
013 |
mapView=(MapView) this .findViewById(R.id.mapview); |
015 |
mapView.setTraffic( true ); |
017 |
mapView.setSatellite( false ); |
019 |
mapView.setStreetView( false ); |
021 |
mapView.setBuiltInZoomControls( true ); |
022 |
mapView.setClickable( true ); |
023 |
mapView.setEnabled( true ); |
025 |
mapController=mapView.getController(); |
026 |
mapController.setZoom( 15 ); |
028 |
myOverLay= new MyOverLay(); |
029 |
List<Overlay> overLays=mapView.getOverlays(); |
030 |
overLays.add(myOverLay); |
032 |
Criteria criteria= new Criteria(); |
033 |
criteria.setAccuracy(Criteria.ACCURACY_FINE); |
034 |
criteria.setAltitudeRequired( false ); |
035 |
criteria.setBearingRequired( false ); |
036 |
criteria.setCostAllowed( false ); |
037 |
criteria.setPowerRequirement(Criteria.POWER_LOW); |
039 |
String provider=locationManager.getBestProvider(criteria, true ); |
041 |
Location location=locationManager.getLastKnownLocation(provider); |
042 |
updateWithLocation(location); |
044 |
locationManager.requestLocationUpdates(provider, 3000 , 0 , locationListener); |
048 |
public boolean onCreateOptionsMenu(Menu menu) { |
050 |
menu.add( 0 , 1 , 1 , "交通模式" ); |
051 |
menu.add( 0 , 2 , 2 , "卫星模式" ); |
052 |
menu.add( 0 , 3 , 3 , "街景模式" ); |
054 |
return super .onCreateOptionsMenu(menu); |
057 |
public boolean onOptionsItemSelected(MenuItem item) { |
059 |
super .onOptionsItemSelected(item); |
060 |
switch (item.getItemId()) { |
062 |
mapView.setTraffic( true ); |
063 |
mapView.setSatellite( false ); |
064 |
mapView.setStreetView( false ); |
067 |
mapView.setSatellite( true ); |
068 |
mapView.setStreetView( false ); |
069 |
mapView.setTraffic( false ); |
072 |
mapView.setStreetView( true ); |
073 |
mapView.setTraffic( false ); |
074 |
mapView.setSatellite( false ); |
077 |
mapView.setTraffic( true ); |
078 |
mapView.setSatellite( false ); |
079 |
mapView.setStreetView( false ); |
084 |
private void updateWithLocation(Location location){ |
087 |
myOverLay.setLocation(location); |
088 |
GeoPoint geoPoint= new GeoPoint(( int )(location.getLatitude()*1E6), ( int )(location.getLongitude()*1E6)); |
090 |
mapController.animateTo(geoPoint); |
091 |
mapController.setZoom( 15 ); |
094 |
private final LocationListener locationListener= new LocationListener() { |
097 |
public void onStatusChanged(String provider, int status, Bundle extras) { |
103 |
public void onProviderEnabled(String provider) { |
109 |
public void onProviderDisabled(String provider) { |
115 |
public void onLocationChanged(Location location) { |
117 |
updateWithLocation(location); |
120 |
class MyOverLay extends Overlay{ |
122 |
private Location location; |
123 |
public void setLocation(Location location){ |
124 |
this .location=location; |
128 |
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, |
131 |
super .draw(canvas, mapView, shadow); |
132 |
Paint paint= new Paint(); |
133 |
Point myScreen= new Point(); |
135 |
GeoPoint geoPoint= new GeoPoint(( int )(location.getLatitude()*1E6), ( int )(location.getLongitude()*1E6)); |
136 |
mapView.getProjection().toPixels(geoPoint, myScreen); |
137 |
paint.setStrokeWidth( 1 ); |
138 |
paint.setARGB( 255 , 255 , 0 , 0 ); |
139 |
paint.setStyle(Paint.Style.STROKE); |
140 |
Bitmap bmp=BitmapFactory.decodeResource(getResources(), R.drawable.mypicture); |
142 |
canvas.drawBitmap(bmp, myScreen.x, myScreen.y,paint); |
143 |
canvas.drawText( "天堂没有路" , myScreen.x, myScreen.y, paint); |
149 |
protected boolean isRouteDisplayed() { |
154 |
public boolean onKeyDown( int keyCode, KeyEvent event) { |
157 |
if (keyCode == KeyEvent.KEYCODE_BACK) { |
158 |
AlertDialog.Builder builder = new AlertDialog.Builder( this ); |
159 |
builder.setMessage( "你确定退出吗?" ) |
160 |
.setCancelable( false ) |
161 |
.setPositiveButton( "确定" , |
162 |
new DialogInterface.OnClickListener() { |
163 |
public void onClick(DialogInterface dialog, |
165 |
MyMapActivity. this .finish(); |
167 |
.killProcess(android.os.Process |
169 |
android.os.Process.killProcess(android.os.Process.myTid()); |
170 |
android.os.Process.killProcess(android.os.Process.myUid()); |
173 |
.setNegativeButton( "返回" , |
174 |
new DialogInterface.OnClickListener() { |
175 |
public void onClick(DialogInterface dialog, |
180 |
AlertDialog alert = builder.create(); |
185 |
return super .onKeyDown(keyCode, event); |
接下来看一下运行后效果:
可以放大缩小:
可是使用menu键,切换不同的模式:
上面是切换到了卫星模式。由于地图需要耗费大量的网络资源,如果网络比较慢的话会等待很长时间。
转自:http://blog.csdn.net/wangkuifeng0118/article/details/7244364