寫於 2013/06/06
因為想在 Android App 上玩玩看 Google Map 的應用,所以開始研究如何把 Google Map 嵌入自己的 AP裡,整理自己研究後的心得和步驟如下:
1. 開發環境安裝
除了標準的 IDE 環境外{Eclipse},你還需要以下兩個 extra packages才能在你的環境裡開發 Google Map V2 相關的App,這兩個 packages 都可以透過 Android SDK Manager 下載到你的開發環境裡- Android support library
- Google Play Service
2. 開啟 Google Map API 服務及 Key 的申請和安裝
你需要到 Google Console 上作兩件事情- 開啟 Google Map API V2 服務
- 用你的憑證所產生的SHA-1註冊你的 App,並得到 Google Map API V2 的 Key
接下來註冊你的 App 並取得 Key這個步驟比較麻煩,首先你必須要準備一個 SHA-1 Hash ,而這個 Hash 必須是從用來 Sign 你的 APK 的憑證所產生的,看了一堆文件都說要用 Java JDK 的 Keytool 來產生 SHA-1 Hash。但如果你是使用 Eclipse ,這邊有一個簡單的方式:
首先點選 "Window" -> "Preferences" 叫出 Preferences 對話視窗,在對話視窗左邊選擇 "Android" -> "Build"
Debug Keystore 是指你用來 sign APK 的 Key 的存放位置
SHA-1 fingerprint 的內容即是你要拿去 Google Console 申請 Google Map API V2 的 Key 用的
請注意,debug key 是 debug 階段拿來用的,一般正式出貨上架時會用另一組正式的 Key 來 Sign APK。因此,相對應的 API Key 也要用 release Key 所產生的 SHA-1去申請註冊。
3. 新增新的專案,並匯入Google Play Service
開啟 Eclipse 已準備新增一個 Android Application project,這時候你必須要了解 API Level 和 Google Map API 版本之間的關係。在 API Level 12 之後才支援 V2,所以你必須考慮好你所支援的 Android 版本,當你的 App 僅支援 API Level 12 之後,基本上只需要考慮一種狀況。如果你必須考慮運行於 API Level 11或更早之前的系統,仍然是可以的,只是必須多一些考量,這在第四點撰寫程式的時候會提到。Okay,你的專案已經新增好了,接下來在寫程式前要做好下面兩件事:
- Import Google Play Service
- Add Google Play service library in your project build environment
Press "File" -> "Import..." 開啟 Import 的對話視窗:
選取 import 的 type 是 "Existing Android Code into Workspace",按下 "Next" button 會跳出 import 視窗,按下 "Browse" button 選取你剛剛安裝的 Google Play Service library,其路徑是在你的 SDK 安裝目錄裡的 "\extras\google\google_play_services\libproject\google-play-services_lib"。
選完之後,即會出現如上圖紅色框框裡的 Google Play Service專案,勾選之後按下 "Next" button 及完成了 Google Play Service 的匯入。
Press "Project" -> "Properties" 開啟 Android project properties 如下圖,選擇 "Android"。
在視窗左下角按"Add" button 選擇要加入的 library
你會看到綠色勾勾,如果哪時候看到的是紅色叉叉就代表有問題。
記住 "Is Library" 那個 option 千萬不能勾選,那代表你的專案最後是要 build 成 library。
按下 OK button 之後,代表你的 project build 已經可以使用指定的 library了。
4. 撰寫程式碼
這邊只是談論如何初步的把 Google Map 嵌入到你的 App,其他進階的應用待以後有空的時候再摸索。基本上分成兩部分:
- 在 AndroidManifest.xml 中宣告需要的 permission 和 Google Map API Key
- 在 Activity Layout file 中宣告 Google Map element 的位置
關於 AndroidManifest.xml,範例如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.Maptest"
android:versionCode="1" android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="12"
android:targetSdkVersion="17" />
<permission
android:name="com.test.Maptest.permission.MAPS_RECEIVE"
android:protectionLevel="signature"/>
<uses-permission android:name="com.test.Maptest.permission.MAPS_RECEIVE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.test.Maptest.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="YOUR_API_KEY"/>
</application>
</manifest>
Layout file:
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment"
xmlns:map="http://schemas.android.com/apk/res-auto"
map:cameraBearing="45"
map:cameraTargetLat="25.033611"
map:cameraTargetLng="121.565000"
map:cameraTilt="0"
map:cameraZoom="13"
map:mapType="normal"
map:uiCompass="true"
map:uiRotateGestures="true"
map:uiScrollGestures="true"
map:uiTiltGestures="true"
map:uiZoomControls="false"
map:uiZoomGestures="true"/>
Reference
Google Developer - Google Maps Android API v2Showing current location in Google Maps using API V2 with SupportMapFragment
後 記
為了搞定 Google Map API V2,前前後後摸索了很久,大部分的時間都花在只為了搞定 "gms.maps.MapFragment" ClassNotFound exception 這個問題。看了非常多的論壇討論,發現所有該加的都加了,也做了檢查再檢查,還是無解。最後大絕招是重開一次專案把上面的 3 和 4 重做一次,發現 ClassNotFound 的問題解決了!!我推測應該是在一開始摸索的時候東試試、西試試的,把某些系統的設定檔搞壞了,
導致 apk build 出來的時候相關 GMS Map class 的參考路徑是錯的...