第二十一章 Google Map

聲明

自從GoogleMap開始要求付費後, 本章節就不再維護更新, 也建議大家不要再使用GoogleMap, 請改用Mapbox. 

Mapbox的開發方式, 請參閱本人撰寫的 MapBox for Android

開發步驟

Google Play 服務

Google在2013年2月推出Google Map Android API v2, 新增了3D顯示等功能. 為了能讓舊的裝置也能使用新功能, Google將這些API包裝成Google Play Service, 並放在Google Play中提供下載. 所以現在若要使用Google Map, 就要先安裝Google Play 服務

Google Developers Console

當我們要使用雲端進行資料存取時, 第一個動作就是要輸入帳號密碼進行登入. 相對的, 存取Google Map的雲端資料, 當然也要有登入的動作. 但Google的雲端相當的多, 不是只有Google Map而以, 所以Google採用金鑰進行登入. 而這些金鑰都在Google Developers Console集中管理.

登入網址 https://console.developers.google.com  , 第一次登入, 需同意其條款, 並建立專案名稱

android_map_1

取得金鑰

在Andrid Studio 新增一個專案, 再選擇Google Map Activity. 開啟google_maps_api.xml, 複制裏面的網址並於瀏覽器開啟, 然後選擇剛建立的專案, 再按建立API金鑰, 就可以取得如下的畫面

android_map_2

將金鑰複制, 回到Android Studio, 於google_map_api.xml裏, 找到 “YOUR_KEY_HERE” 將之取代貼上. 執行安裝此專案後, 就可以看到Google Map了

啟用API

map_2

然後選用Google Maps Android API, 再按下啟用

map_3

上述啟用API後, 要數分鐘才能生效

專案架構

上述專案中, 都是Android studio自動完成, 只加入金鑰即可執行. 稍微了解一下整個專案的架構如下

專案建置檔gradle加入如下dependencies

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.0.1'
    compile 'com.google.android.gms:play-services:10.0.1'
    testCompile 'junit:junit:4.12'
}

畫面配置檔為一個fragment

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.asuscomm.mahaljsp.googlemap.MapsActivity" />

Activity活動元件為繼承了FragmentActivity並實作了OnMapReadyCallback interface

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
    private GoogleMap mMap;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // Add a marker in Sydney and move the camera
        LatLng sydney = new LatLng(-34, 151);
        mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
    }
}

設定檔則加入了ACCESS_FINE_LOCATION權限, 及<meta-data>標簽, 設定了金鑰

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application ...>
    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="@string/google_maps_key" />
    <activity ...>
        ....
    </activity>
</application>

設定地圖類型

地圖種類有五種, 可使用setMapType(int)來設定, 五種地圖如下
MAP_TYPE_NONE : 不顯示
MAP_TYPE_NORMAL : 一般
MAP_TYPE_SATELLITE : 衛星空照
MAP_TYPE_TERRIAN : 地形
MAP_TYPE_HYBRID : 衛星加街道名

為了切換這五種, 在畫面設定檔中加為一個Spinner元件, 如下

activity_maps2.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    <Spinner
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/spinner" />
</RelativeLayout>

另新增res/values/arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="type_array">
        <item>不顯示</item>
        <item>一般</item>
        <item>衛星</item>
        <item>地形</item>
        <item>混合</item>
    </string-array>
</resources>

MapsActivity.java改為如下

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps2);
    processViews();
    processControllers();
}
public void processViews(){
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
    spinner=(Spinner)findViewById(R.id.spinner);
}
public void processControllers(){
    spinner.setAdapter(ArrayAdapter.createFromResource(
            this,
            R.array.type_array,
            android.R.layout.simple_spinner_dropdown_item));
    spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
            switch(position){
                case 0:
                    mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
                    break;
                case 1:
                    mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                    break;
                case 2:
                    mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
                    break;
                case 3:
                    mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
                    break;
                case 4:
                    mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
                    break;
            }
        }
        @Override
        public void onNothingSelected(AdapterView<?> adapterView) {}
    });
}

完整程式碼下載 : GoogleMap.rar

地圖操作

常用的地圖控制, 有放大縮小, 旋轉, 平移, 顯示交通流量等, 其控制方法如下
setTrafficEnabled(boolean)
setZoomControlsEnabled(boolean)
setCompassEnabled(boolean)
setScrollGesturesEnabled(boolean) : 移動地圖
setZoomGestureEnabled(boolean)
setRotateGesturesEnabled(boolean)
setMyLocationEnabled(boolean)
setMyLocationButtonEnabled()

取得狀態有如下
isZoomControllsEnabled()
isCompassEnabled()
isScrollGesturesEnabled()
isZoomGesturesEnabled()
isTiltGesturesEnabled()
isRotateGesturesEnabled()
isTrafficEnabled()
isMyLocationEanbled()
isMyLocationButtonEnabled()

 完整程式碼下載 : GoogleMap2.rar

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *