Android Google Map API使用的八個步驟


本系列教程將分為兩部分,第一部分是指導用戶使用Mapview控件進行編程,其中包括了如何獲得Google Map API,如何使用該API進行簡單的開發,如何獲得用戶當前所在的位置。第二部分則包括如何在地圖上,用第三方的組件庫,實現氣球式顯示若干指定位置的功能。

  步驟1 創建新的Android 工程

  首先打開eclipse新建立一個Android 工程,其中相關參數設置如下:

  Project name:MallFinder

  Build Target: Google APIs Platform – 2.1 API Level 7

  Application Name: Mall Finder

  Package Name: com.shawnbe.mallfinder

  Create Activity: MallFinderActivity

  MinimumSDK: 7

  如下圖所示:

 

 

  步驟2 注冊Google Map API key

  由於在使用google map的時候,需要使用google map api的key,因此需要先注冊一個開發者key,可以到如下地址進行注冊:http://code.google.com/android/add-ons/google-apis/mapkey.html ,其中需要我們先產生開發期間的md5 密紋才能完成注冊,因此我們先學習如何生成一個MD5密紋。

  我們需要使用keytool工具,不使用傳統的命令行方式下那枯燥的證書簽名生成辦法,而是直接在eclipse下通過插件進行完成,詳細見步驟3

  步驟3 安裝keytool插件

  在eclipse的Help菜單中,如下圖,選擇安裝新軟件:

 

  在安裝地址中輸入如下地址:http://www.keytool.sourceforge.net/update  ,如下圖

 

  接下來會加載相關的安裝程序,並顯示用戶協議,選擇接受所有用戶協議后進行安裝,安裝成功后重新啟動eclipse即可生效。

  步驟4 產生開發期間的MD5密鑰

  在重新啟動eclipse后,會發現工具欄多了如下圖的keytool菜單

 

  現在,我們打開debug.keystore,注意其位置回因操作系統不同而有不同

  Windows Vista : C:\Users\\.android\debug.keystore

  Windows XP : C:\Documents and Settings\\.android\debug.keystore

  OS X 和 Linux : ~/.android/debug.keystore

  點keytool菜單中,選擇open keystore,根據提示,選擇當前系統所在的debug.keystore位置並打開,如下圖,

 

  其中,輸入密碼默認為android即可,並點Load加載。之后會在eclipse中出現新的keytool的視圖,如下圖所示:

 

  雙擊打開androiddebugkey,復制其md5密紋,然后訪問頁面

  http://code.google.com/android/maps-api-signup.html ,接受其協議,將md5密紋復制進去,再點Generate API Key,即產生google map的api key,記得保存好這個KEY,在接下來的步驟中要使用。

 

  步驟5 增加MapView控件

  接下來,我們可以往布局文件中增加MapView控件。我們在main.xml中添加如下代碼:

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" > 
    <FrameLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"> 
        <com.google.android.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true"
        android:apiKey="你的GOOGLE MAP API KEY "/> 
    </FrameLayout> 
</LinearLayout>

  在這個控件中,請注意要在android:apiKey的位置填入剛申請的google map api key。

  步驟6 設置相關的權限

  由於我們的應用需要調用Google Map的數據,以及通過手機的GPS獲得相關的其他地理位置數據,因此我們必須在Android的Manifest文件中進行權限的設置。

  我們打開AndroidManifest.xml文件,然后增加如下代碼所示的權限設置,注意添加在標簽后,但要在標簽前。

<uses-feature android:name="android.hardware.location.gps"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.INTERNET"/>

  在這里,我們分別調用了gps位置服務權限,使用互聯網的權限以及使用最佳位置查找的權限(FINE_LOCATION)。在本文中,其實沒用到FINE_LOCATION,但只是告訴開發者可以調整使用不同的地理位置提供者(providers)以提供准確的位置服務,如果要有比較精確的地理位置服務,那么可以設置android.permisson.ACCESS_FINE_LOCATION服務。要注意的是在開發中,不要過多引用一些不需要使用的權限設置,否則會給用戶帶來擔憂安全等問題。要是只想調用一般的位置服務,可以使用普通的android.permission.ACCESS_COARSE_LOCATION權限。

  為了在應用中使用Google Map,需要在Manifest文件中包含相關的類庫文件,所以加入如下代碼:

     <uses-library android:required="true" android:name="com.google.android.maps" />

  為了視覺的美觀,我們把標題欄也去掉,以便留給地圖更大的空間,所以設置為

  android:theme="@android:style/Theme.NoTitleBar"

  下面是完整的Manifest文件代碼:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.shawnbe.mallfinder"
    android:versionCode="1"
    android:versionName="1.0" > 
    <uses-sdk android:minSdkVersion="7" /> 
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.NoTitleBar"> 
        <activity
            android:label="@string/app_name"
            android:name=".MallFinderActivity" > 
            <intent-filter > 
                <action android:name="android.intent.action.MAIN" /> 
  
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
        </activity> 
        <uses-library android:required="true" android:name="com.google.android.maps" /> 
    </application> 
    <uses-feature android:name="android.hardware.location.gps"/> 
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
    <uses-permission android:name="android.permission.INTERNET"/> 
</manifest>

  步驟7 設置MapView

  下面對主activity程序(MallFinderActivity.java)進行修改,首先讓其繼承MapActivity類,如下:

  public class MallFinderActivity extends MapActivity {

  由於繼承了MapActivity類,因此必須實現isRouteDisplayed方法,這個方法是用來做路線導航用的,這里我們不需要,因此只需要簡單返回false即可:

  @Override

  protected boolean isRouteDisplayed() {

  // TODO Auto-generated method stub

  return false;

  }

  接下來我們就可以聲明MapController控件,並對其進行相關屬性的設置了,首先是聲明控件

  private MapController mapController;

  private MapView mapView;

  並在oncreate方法中進行屬性設置如下:

mapView = (MapView)findViewById(R.id.mapView); 
mapView.setBuiltInZoomControls(true); 
mapView.setSatellite(false); 
mapView.setStreetView(true); 
mapController = mapView.getController(); 
mapController.setZoom(13);

  在上面的代碼中,設置了地圖顯示的方式為街道模式(通過設置mapview的setStreetView屬性值為true),並且通過mapView.setBuiltInZoomControls(true); 使用了系統內置的放大縮小功能,並設置了地圖的放大縮小倍數為13。

  這個時候我們就可以選擇運行應用,看下是否符合我們的初步預期效果,運行后效果如下圖:

 

 

  步驟8 獲得當前所在位置

  在LBS應用中,十分重要的工作是要獲得當前設備所在的位置,這個可以使用locationManager類實現,在獲得當前位置的時候是需要花費一些時間的。我們繼續聲明兩個參數變量如下:

  private LocationManager locationManager;

  private GeoPoint currentLocation;

  分別聲明了LocationManager類的實例和GeoPoint類的實例(用於下文中的經緯度的計算)。

  再增加如下幾個方法:

public void getLastLocation(){ 
    String provider = getBestProvider(); 
    currentLocation = locationManager.getLastKnownLocation(provider); 
    if(currentLocation != null){ 
        setCurrentLocation(currentLocation); 
    } 
    else
    { 
        Toast.makeText(this, "Location not yet acquired", Toast.LENGTH_LONG).show(); 
    } 

  
public void animateToCurrentLocation(){ 
    if(currentPoint!=null){ 
        mapController.animateTo(currentPoint); 
    } 

  
public String getBestProvider(){ 
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
    Criteria criteria = new Criteria(); 
    criteria.setPowerRequirement(Criteria.NO_REQUIREMENT); 
    criteria.setAccuracy(Criteria.NO_REQUIREMENT); 
    String bestProvider = locationManager.getBestProvider(criteria, true); 
    return bestProvider; 

  
public void setCurrentLocation(Location location){ 
    int currLatitude = (int) (location.getLatitude()*1E6); 
    int currLongitude = (int) (location.getLongitude()*1E6); 
    currentLocation = new GeoPoint(currLatitude,currLongitude); 
  
    currentLocation = new Location(""); 
    currentLocation.setLatitude(currentPoint.getLatitudeE6() / 1e6); 
    currentLocation.setLongitude(currentPoint.getLongitudeE6() / 1e6); 
}

  並且在oncreate方法中,添加對以上方法的調用代碼如下:

  public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    mapView = (MapView)findViewById(R.id.mapView); 
    mapView.setBuiltInZoomControls(true); 
    mapView.setSatellite(false); 
    mapView.setStreetView(true); 
    mapController = mapView.getController(); 
    mapController.setZoom(13); 
    getLastLocation(); 
    animateToCurrentLocation(); 
}

  首先,在getLastLocation這個方法中,創建了locationManager類的實例並且根據設置的條件返回一個合適的地理位置提供方法。在這里,我們並沒有指定對地理位置提供者的查詢條件,在實際應用中,開發者可以通過設置criteria.setAccuracy()和criteria.setPowerRequirement()方法進行查找。如果要使用最精確的provider的話,可以設置使用ACCURACY_FINE方法進行搜索,如下代碼所示:

  criteria.setAccuracy(Criteria.ACCURACY_FINE);

  在本文中之所以不選擇使用最准確的位置provider主要是因為是沒在室外進行測試,都是在室內調試程序,建議開發完后換成GPS模式provider到室外進行調試那樣將看到很好的效果。

  接下來代碼中使用 currentLocation = locationManager.getLastKnownLocation(provider); 一句,獲得最新的位置信息,並且在setCurrentLocation方法中,對通過prodiver獲得的地理位置信息Location對象進行經緯度的轉換為GeoPoint對象。然后調用animateToCurrentLocation方法,將地圖的中心點定位到我們當前的位置上去。

  此外,由於我們的位置是會發生變化的,所以需要使用location 監聽器去檢測我們的位置變化,這時需要實現locationListener接口,如下所示:

  public class MallFinderActivity extends MapActivity implements LocationListener{

  同時我們需要實現LocationListener類的以下幾個方法:

  @Override
public void onLocationChanged(Location arg0) { 
    // TODO Auto-generated method stub 

  
@Override
public void onProviderDisabled(String arg0) { 
    // TODO Auto-generated method stub 

  
@Override
public void onProviderEnabled(String arg0) { 
    // TODO Auto-generated method stub 

  
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) { 
    // TODO Auto-generated method stub 
}

  其中這里我們關心的是需要實現onLocationChanged方法,這里我們調用之前編寫好的setlocation方法,獲得當前的最新位置,如下:

    @Override
public void onLocationChanged(Location newLocation) { 
    // TODO Auto-generated method stub 
    setCurrentLocation(newLocation); 
}

  為了完善程序,在程序處在onResume及onPause狀態下都能及時更新地理位置信息以及取消更新,加上如下代碼:

   @Override
protected void onResume() { 
    super.onResume(); 
    locationManager.requestLocationUpdates(getBestProvider(), 1000, 1, this); 

  
@Override
protected void onPause() { 
    super.onPause(); 
    locationManager.removeUpdates(this); 
}

  小結

  在本系列的第一講中,分步講解了如何注冊Google API KEY以及Mapview控件基本方法的使用,還有讓讀者了解到使用google map的初步步驟,在下一講中,將指導讀者如何對地圖上的位置進行標注。

 

本系列教程將分為兩部分,第一部分是指導用戶使用Mapview控件進行編程,其中包括了如何獲得Google Map API,如何使用該API進行簡單的開發,如何獲得用戶當前所在的位置。第二部分則包括如何在地圖上,用第三方的組件庫,實現氣球式顯示若干指定位置的功能。

  步驟1 創建新的Android 工程

  首先打開eclipse新建立一個Android 工程,其中相關參數設置如下:

  Project name:MallFinder

  Build Target: Google APIs Platform – 2.1 API Level 7

  Application Name: Mall Finder

  Package Name: com.shawnbe.mallfinder

  Create Activity: MallFinderActivity

  MinimumSDK: 7

  如下圖所示:

 

 

  步驟2 注冊Google Map API key

  由於在使用google map的時候,需要使用google map api的key,因此需要先注冊一個開發者key,可以到如下地址進行注冊:http://code.google.com/android/add-ons/google-apis/mapkey.html ,其中需要我們先產生開發期間的md5 密紋才能完成注冊,因此我們先學習如何生成一個MD5密紋。

  我們需要使用keytool工具,不使用傳統的命令行方式下那枯燥的證書簽名生成辦法,而是直接在eclipse下通過插件進行完成,詳細見步驟3

  步驟3 安裝keytool插件

  在eclipse的Help菜單中,如下圖,選擇安裝新軟件:

 

  在安裝地址中輸入如下地址:http://www.keytool.sourceforge.net/update  ,如下圖

 

  接下來會加載相關的安裝程序,並顯示用戶協議,選擇接受所有用戶協議后進行安裝,安裝成功后重新啟動eclipse即可生效。

  步驟4 產生開發期間的MD5密鑰

  在重新啟動eclipse后,會發現工具欄多了如下圖的keytool菜單

 

  現在,我們打開debug.keystore,注意其位置回因操作系統不同而有不同

  Windows Vista : C:\Users\\.android\debug.keystore

  Windows XP : C:\Documents and Settings\\.android\debug.keystore

  OS X 和 Linux : ~/.android/debug.keystore

  點keytool菜單中,選擇open keystore,根據提示,選擇當前系統所在的debug.keystore位置並打開,如下圖,

 

  其中,輸入密碼默認為android即可,並點Load加載。之后會在eclipse中出現新的keytool的視圖,如下圖所示:

 

  雙擊打開androiddebugkey,復制其md5密紋,然后訪問頁面

  http://code.google.com/android/maps-api-signup.html ,接受其協議,將md5密紋復制進去,再點Generate API Key,即產生google map的api key,記得保存好這個KEY,在接下來的步驟中要使用。

 

  步驟5 增加MapView控件

  接下來,我們可以往布局文件中增加MapView控件。我們在main.xml中添加如下代碼:

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" > 
    <FrameLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"> 
        <com.google.android.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true"
        android:apiKey="你的GOOGLE MAP API KEY "/> 
    </FrameLayout> 
</LinearLayout>

  在這個控件中,請注意要在android:apiKey的位置填入剛申請的google map api key。

  步驟6 設置相關的權限

  由於我們的應用需要調用Google Map的數據,以及通過手機的GPS獲得相關的其他地理位置數據,因此我們必須在Android的Manifest文件中進行權限的設置。

  我們打開AndroidManifest.xml文件,然后增加如下代碼所示的權限設置,注意添加在標簽后,但要在標簽前。

<uses-feature android:name="android.hardware.location.gps"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.INTERNET"/>

  在這里,我們分別調用了gps位置服務權限,使用互聯網的權限以及使用最佳位置查找的權限(FINE_LOCATION)。在本文中,其實沒用到FINE_LOCATION,但只是告訴開發者可以調整使用不同的地理位置提供者(providers)以提供准確的位置服務,如果要有比較精確的地理位置服務,那么可以設置android.permisson.ACCESS_FINE_LOCATION服務。要注意的是在開發中,不要過多引用一些不需要使用的權限設置,否則會給用戶帶來擔憂安全等問題。要是只想調用一般的位置服務,可以使用普通的android.permission.ACCESS_COARSE_LOCATION權限。

  為了在應用中使用Google Map,需要在Manifest文件中包含相關的類庫文件,所以加入如下代碼:

     <uses-library android:required="true" android:name="com.google.android.maps" />

  為了視覺的美觀,我們把標題欄也去掉,以便留給地圖更大的空間,所以設置為

  android:theme="@android:style/Theme.NoTitleBar"

  下面是完整的Manifest文件代碼:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.shawnbe.mallfinder"
    android:versionCode="1"
    android:versionName="1.0" > 
    <uses-sdk android:minSdkVersion="7" /> 
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.NoTitleBar"> 
        <activity
            android:label="@string/app_name"
            android:name=".MallFinderActivity" > 
            <intent-filter > 
                <action android:name="android.intent.action.MAIN" /> 
  
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
        </activity> 
        <uses-library android:required="true" android:name="com.google.android.maps" /> 
    </application> 
    <uses-feature android:name="android.hardware.location.gps"/> 
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
    <uses-permission android:name="android.permission.INTERNET"/> 
</manifest>

  步驟7 設置MapView

  下面對主activity程序(MallFinderActivity.java)進行修改,首先讓其繼承MapActivity類,如下:

  public class MallFinderActivity extends MapActivity {

  由於繼承了MapActivity類,因此必須實現isRouteDisplayed方法,這個方法是用來做路線導航用的,這里我們不需要,因此只需要簡單返回false即可:

  @Override

  protected boolean isRouteDisplayed() {

  // TODO Auto-generated method stub

  return false;

  }

  接下來我們就可以聲明MapController控件,並對其進行相關屬性的設置了,首先是聲明控件

  private MapController mapController;

  private MapView mapView;

  並在oncreate方法中進行屬性設置如下:

mapView = (MapView)findViewById(R.id.mapView); 
mapView.setBuiltInZoomControls(true); 
mapView.setSatellite(false); 
mapView.setStreetView(true); 
mapController = mapView.getController(); 
mapController.setZoom(13);

  在上面的代碼中,設置了地圖顯示的方式為街道模式(通過設置mapview的setStreetView屬性值為true),並且通過mapView.setBuiltInZoomControls(true); 使用了系統內置的放大縮小功能,並設置了地圖的放大縮小倍數為13。

  這個時候我們就可以選擇運行應用,看下是否符合我們的初步預期效果,運行后效果如下圖:

 

 

  步驟8 獲得當前所在位置

  在LBS應用中,十分重要的工作是要獲得當前設備所在的位置,這個可以使用locationManager類實現,在獲得當前位置的時候是需要花費一些時間的。我們繼續聲明兩個參數變量如下:

  private LocationManager locationManager;

  private GeoPoint currentLocation;

  分別聲明了LocationManager類的實例和GeoPoint類的實例(用於下文中的經緯度的計算)。

  再增加如下幾個方法:

public void getLastLocation(){ 
    String provider = getBestProvider(); 
    currentLocation = locationManager.getLastKnownLocation(provider); 
    if(currentLocation != null){ 
        setCurrentLocation(currentLocation); 
    } 
    else
    { 
        Toast.makeText(this, "Location not yet acquired", Toast.LENGTH_LONG).show(); 
    } 

  
public void animateToCurrentLocation(){ 
    if(currentPoint!=null){ 
        mapController.animateTo(currentPoint); 
    } 

  
public String getBestProvider(){ 
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
    Criteria criteria = new Criteria(); 
    criteria.setPowerRequirement(Criteria.NO_REQUIREMENT); 
    criteria.setAccuracy(Criteria.NO_REQUIREMENT); 
    String bestProvider = locationManager.getBestProvider(criteria, true); 
    return bestProvider; 

  
public void setCurrentLocation(Location location){ 
    int currLatitude = (int) (location.getLatitude()*1E6); 
    int currLongitude = (int) (location.getLongitude()*1E6); 
    currentLocation = new GeoPoint(currLatitude,currLongitude); 
  
    currentLocation = new Location(""); 
    currentLocation.setLatitude(currentPoint.getLatitudeE6() / 1e6); 
    currentLocation.setLongitude(currentPoint.getLongitudeE6() / 1e6); 
}

  並且在oncreate方法中,添加對以上方法的調用代碼如下:

  public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    mapView = (MapView)findViewById(R.id.mapView); 
    mapView.setBuiltInZoomControls(true); 
    mapView.setSatellite(false); 
    mapView.setStreetView(true); 
    mapController = mapView.getController(); 
    mapController.setZoom(13); 
    getLastLocation(); 
    animateToCurrentLocation(); 
}

  首先,在getLastLocation這個方法中,創建了locationManager類的實例並且根據設置的條件返回一個合適的地理位置提供方法。在這里,我們並沒有指定對地理位置提供者的查詢條件,在實際應用中,開發者可以通過設置criteria.setAccuracy()和criteria.setPowerRequirement()方法進行查找。如果要使用最精確的provider的話,可以設置使用ACCURACY_FINE方法進行搜索,如下代碼所示:

  criteria.setAccuracy(Criteria.ACCURACY_FINE);

  在本文中之所以不選擇使用最准確的位置provider主要是因為是沒在室外進行測試,都是在室內調試程序,建議開發完后換成GPS模式provider到室外進行調試那樣將看到很好的效果。

  接下來代碼中使用 currentLocation = locationManager.getLastKnownLocation(provider); 一句,獲得最新的位置信息,並且在setCurrentLocation方法中,對通過prodiver獲得的地理位置信息Location對象進行經緯度的轉換為GeoPoint對象。然后調用animateToCurrentLocation方法,將地圖的中心點定位到我們當前的位置上去。

  此外,由於我們的位置是會發生變化的,所以需要使用location 監聽器去檢測我們的位置變化,這時需要實現locationListener接口,如下所示:

  public class MallFinderActivity extends MapActivity implements LocationListener{

  同時我們需要實現LocationListener類的以下幾個方法:

  @Override
public void onLocationChanged(Location arg0) { 
    // TODO Auto-generated method stub 

  
@Override
public void onProviderDisabled(String arg0) { 
    // TODO Auto-generated method stub 

  
@Override
public void onProviderEnabled(String arg0) { 
    // TODO Auto-generated method stub 

  
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) { 
    // TODO Auto-generated method stub 
}

  其中這里我們關心的是需要實現onLocationChanged方法,這里我們調用之前編寫好的setlocation方法,獲得當前的最新位置,如下:

    @Override
public void onLocationChanged(Location newLocation) { 
    // TODO Auto-generated method stub 
    setCurrentLocation(newLocation); 
}

  為了完善程序,在程序處在onResume及onPause狀態下都能及時更新地理位置信息以及取消更新,加上如下代碼:

   @Override
protected void onResume() { 
    super.onResume(); 
    locationManager.requestLocationUpdates(getBestProvider(), 1000, 1, this); 

  
@Override
protected void onPause() { 
    super.onPause(); 
    locationManager.removeUpdates(this); 
}

  小結

  在本系列的第一講中,分步講解了如何注冊Google API KEY以及Mapview控件基本方法的使用,還有讓讀者了解到使用google map的初步步驟,在下一講中,將指導讀者如何對地圖上的位置進行標注。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM