在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-permissionandroid: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