連續幾天調試,終於可以讓自己的map程式顯示出地圖了,經驗積累如下:
地圖顯示需要mapview類,該類應放在mapactivity中,controller則可以控制地圖的伸縮大小(從mapview中得來)。
當然首先我們必須保證申請到apikey,具體資訊可參考
http://code.google.com/intl/zh-CN/android/add-ons/google-apis/maps-overview.html
先來看下布局檔案:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/maplayout" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.google.android.maps.MapViewandroid:id="@+id/viewMap"android:enabled="true"android:clickable="true"android:layout_width="fill_parent"android:layout_height="fill_parent"android:apiKey="0shqezR5L4dW47pyzE4RxOTIOV1lqoP6uInPQGw"/><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" ><TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="@string/lat" android:id="@+id/textView1"></TextView><EditText android:text="EditText" android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/latitude"></EditText><TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="@string/lon" android:id="@+id/textView2"></TextView><EditText android:text="EditText" android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/longitude"></EditText><Button android:id="@+id/showmap" android:text="Button" android:layout_height="wrap_content" android:layout_width="wrap_content"></Button></LinearLayout></RelativeLayout>
將apikey放入代碼中,注意在main.xml這個布局檔案中,mapview標籤需用全稱,如
<com.google.android.maps.MapViewandroid:id="@+id/viewMap"android:enabled="true"android:clickable="true"android:layout_width="fill_parent"android:layout_height="fill_parent"android:apiKey="0shqezR5L4dW47pyzE4RxOTIOV1lqoP6uInPQGw"/>
然後manifest.xml檔案中<application>標籤下添加<uses-library android:name="com.google.android.maps" />,注意要添加
到<application>下(我開始一時大意,添加到了<activity>下)
接下來需要設定程式存取權限,
<manifest>標籤下添加
<uses-permission android:name="android.permission.INTERNET" />
那麼完整的manifest.xml檔案如下:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.test" android:versionCode="1" android:versionName="1.0"> <uses-permission android:name="android.permission.INTERNET" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".MapTest" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity><uses-library android:name="com.google.android.maps" /> </application></manifest>
再貼上java檔案:
package com.test;import com.google.android.maps.*;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.*;public class MapTest extends MapActivity {private MapView viewMap;private Button showbutton;private EditText address_lat;private EditText address_lon;private MapController controller;private double lat = 25.040225;private double lon = 121.52374; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); viewMap = (MapView)findViewById(R.id.viewMap); showbutton = (Button)findViewById(R.id.showmap); address_lat = (EditText)findViewById(R.id.latitude); address_lon = (EditText)findViewById(R.id.longitude); controller = viewMap.getController(); viewMap.setSatellite(false); viewMap.setStreetView(true); controller.setZoom(17); refreshMap(); showbutton.setOnClickListener(new OnClickListener(){ @Overridepublic void onClick(View v) {// TODO Auto-generated method stubboolean input_is_ok = inputCheck();if(input_is_ok){lat = Double.parseDouble(address_lat.getText().toString());lon = Double.parseDouble(address_lon.getText().toString());refreshMap();}else{//showDialog(1);}} }); } private boolean inputCheck() { if(address_lat.getText().toString().equals("") || address_lon.getText().toString().equals("")) return false; else return true; } private void refreshMap() { GeoPoint point = new GeoPoint((int)(lat * 1e6), (int)(lon * 1e6)); viewMap.displayZoomControls(true); controller.animateTo(point); controller.setZoom(17); }@Overrideprotected boolean isRouteDisplayed() {// TODO Auto-generated method stubreturn false;}}
如果你想要實現一個簡單的地圖縮放功能,可以使用mapview中的setBuiltInZoomControls(boolean on)
如:
viewmap.setBuiltInZoomControls(true);
這樣我們可以得到一個控制縮放的控制項。
涉及到GPS定位的問題,還需要用到其他類。
Location,該對象包含地理位置資訊。在跟蹤位置的過程中,我們需要即時的得到Location對象。
通過LocationManager對象中的
public
Location getLastKnownLocation
(String provider)方法我們可以得到當前的location對象。參數provider是locationprovider的名字。LocationProvider根據我現在的理解,該對象指的應該是定位元模式,我們知道定位元模式一般有gps定位,基站定位,network定位,WIFI定位等,android提供給我們兩種provider,分別是:LocationManager.NETWORK_PROVIDER和LocationManager.GPS_PROVIDER
前者用於移動網路中擷取位置,精度較低但速度很快,後者使用GPS進行定位,精度很高但一般需要10-60秒時間才能開始第1次定位,如果是在室內則基本上無法定位。
當然,我們也可以重寫自己的provider。
舉一個簡單的栗子:
package com.test;import java.util.List;import com.google.android.maps.*;import android.app.Activity;import android.content.Context;import android.location.*;import android.os.Bundle;import android.util.Log;import android.widget.*;public class MapUpdate extends MapActivity {private MapView viewmap;private LocationManager managerlocation;private Location currentLocation;private Criteria ct;private MapController mcontrol;private String locpro; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); viewmap = (MapView) findViewById(R.id.viewMap); mcontrol = viewmap.getController(); managerlocation = (LocationManager)getSystemService(Context.LOCATION_SERVICE); viewmap.setBuiltInZoomControls(true); //通過criteria對象,設定位置資料的標準,以便系統根據需要為我們選取合適的provider ct = new Criteria(); ct.setAccuracy(Criteria.ACCURACY_FINE); ct.setAltitudeRequired(false); ct.setBearingRequired(false); ct.setCostAllowed(true); ct.setPowerRequirement(Criteria.POWER_LOW); currentLocation = getCurrentLocation(managerlocation, ct); if (currentLocation == null) { Log.d("test", "currentLocation is null"); } else { refreshMylocation(currentLocation); } LocationListener lolis = new LocationListener(){@Overridepublic void onLocationChanged(Location location) {// TODO Auto-generated method stubrefreshMylocation(location);}@Overridepublic void onProviderDisabled(String provider) {// TODO Auto-generated method stub}@Overridepublic void onProviderEnabled(String provider) {// TODO Auto-generated method stub}@Overridepublic void onStatusChanged(String provider, int status,Bundle extras) {// TODO Auto-generated method stub} }; managerlocation.requestLocationUpdates(locpro, 5000, 10, lolis); } private void refreshMylocation(Location cl) {// TODO Auto-generated method stubdouble lat = cl.getLatitude() * 1e6;double lon = cl.getLongitude() * 1e6;GeoPoint gp = new GeoPoint((int)lat, (int)lon);RouteOverlay routepoint = new RouteOverlay(gp);viewmap.getOverlays().add(routepoint);mcontrol.animateTo(gp);}private Location getCurrentLocation(LocationManager lm, Criteria ct){ Location cl = null; locpro = lm.getBestProvider(ct, true); //Log.d("providername", locpro); try { cl = lm.getLastKnownLocation(locpro); }catch(Exception e){ Log.d("LocationException", e.toString() + " "); e.printStackTrace(); } if (locpro == null) { Log.d("providertest", "locationprovider is null"); } else { Log.d("providertest", "locationprovider is ok"); } if(cl == null) { Log.d("LocationTest", "location is null"); } return cl; }@Overrideprotected boolean isRouteDisplayed() {// TODO Auto-generated method stubreturn false;}}