Kotlin 04.1 の高度な Android: Android Google マップ

この Codelab は、Kotlin での高度な Android 開発コースの一部です。Codelab を順番に進めていくと、このコースを最大限に活用できますが、これは必須ではありません。すべてのコース Codelab は Kotlin での Codelab の高度な Codelab のランディング ページに掲載されています。

Google マップを使ってアプリを作成すると、航空写真、地図上の UI コントロール、位置情報マーカー、位置情報マーカーなど、さまざまな機能をアプリに追加できます。よく知られた釣りスポットやクライミング エリアなど、ご自身のデータセットの情報を提供して、標準の Google マップに追加できます。また、プレーヤーが宝探しや拡張現実などのゲームで現実世界の探検を楽しめるゲームを作成することもできます。

このレッスンでは、カスタムの地図とユーザーの現在地を表示する Wander という Google マップ アプリを作成します。

Prerequisites

以下の知識があること。

  • 基本的な Android アプリを作成し、Android Studio を使用して実行する方法。
  • 文字列などのリソースを作成して管理する方法
  • Android Studio を使用してコードをリファクタリングし、変数の名前を変更する方法
  • Google マップをユーザーとして使用する方法。
  • ランタイム権限を設定する方法。

学習内容

  • Google API Console から API キーを取得してアプリに登録する方法
  • Google マップをアプリに統合する方法
  • さまざまなタイプの地図を表示する方法
  • Google マップのスタイルを設定する方法
  • 地図にマーカーを追加する方法
  • ユーザーがスポット(地図上の場所)にマーカーを配置できるようにする
  • 位置情報の記録を有効にする方法
  • Google マップが埋め込まれた Wander アプリの作成方法
  • マーカーやスタイルなど、アプリのカスタム機能を作成する方法
  • アプリで位置情報の追跡を有効にする方法

この Codelab では、カスタム スタイルで Google マップを表示する Wander アプリを作成します。Wander アプリを使用すると、場所にマーカーをドロップしたり、オーバーレイを追加したり、位置情報をリアルタイムで確認したりできます。

Maps SDK for Android には API キーが必要です。API キーを取得するには、[API とサービス] ページでプロジェクトを登録してください。API キーは、アプリと作成者をリンクするデジタル証明書に関連付けられます。デジタル証明書の使用とアプリへの署名について詳しくは、アプリに署名するをご覧ください。

この Codelab では、デバッグ証明書に API キーを使用します。デバッグ証明書は、デバッグビルドに署名するで説明されているように、安全ではありません。Maps SDK for Android を使用する公開中の Android アプリには 2 つ目の API キー(リリース証明書のキー)が必要です。リリース用証明書の取得について詳しくは、API キーを取得するをご覧ください。

Android Studio には、便利なテンプレート コードを生成する Google マップ アクティビティ テンプレートが用意されています。テンプレート コードには、API キーの取得を容易にするリンクを含む google_maps_api.xml ファイルが含まれています。

ステップ 1: マップ テンプレートを使用して Wander プロジェクトを作成する

  1. 新しい Android Studio プロジェクトを作成します。
  2. [Google Maps Activity] テンプレートを選択します。

  1. プロジェクトに Wander という名前を付けます。
  2. 最小 API レベルを API 19 に設定します。言語が Kotlin であることを確認します。
  3. [Finish] をクリックします。
  4. アプリの作成が完了したら、プロジェクトと、Android Studio が作成した以下のマップ関連のファイルを確認します。

google_maps_api.xml - この構成ファイルを使用して API キーを保持します。テンプレートでは、デバッグ用とリリース用の 2 つの google_maps_api.xml ファイルが生成されます。デバッグ用証明書の API キーのファイルは src/debug/res/values にあります。リリース用証明書の API キーのファイルは、src/release/res/values にあります。この Codelab では、デバッグ証明書のみを使用します。

activity_maps.xml - このレイアウト ファイルには、画面全体に表示する単一のフラグメントが含まれています。SupportMapFragment クラスは Fragment クラスのサブクラスです。SupportMapFragment は、アプリにマップを配置する最も簡単な方法です。必要なライフサイクルのニーズを自動的に処理するために、マップのビューのラッパーです。

任意の ViewGroup<fragment> タグを使用し、追加の name 属性を使用して、レイアウト ファイルに SupportMapFragment を含めることができます。

android:name="com.google.android.gms.maps.SupportMapFragment"

MapsActivity.java - MapsActivity.kt ファイルは onCreate() メソッドで SupportMapFragment をインスタンス化し、そのクラス getMapAsync() を使用してマップシステムとビューを自動的に初期化します。SupportMapFragment を含むアクティビティは、OnMapReadyCallback インターフェースと、そのインターフェースの onMapReady() メソッドを実装する必要があります。onMapReady() メソッドは、地図が読み込まれたときに呼び出されます。

ステップ 2: API キーを取得する

  1. デバッグ版の google_maps_api.xml ファイルを開きます。
  2. このファイルで、長い URL が含まれるコメントを探します。URL パラメータには、アプリに関する具体的な情報が含まれます。
  3. URL をコピーしてブラウザに貼り付けます。
  4. 画面の指示に沿って、[API とサービス] ページにプロジェクトを作成します。指定された URL のパラメータが原因で、このページには Maps SDK for Android が自動的に有効になることが通知されます。
  5. [API キーを作成する] をクリックします。
  6. 次のページで [API キー] セクションに移動し、作成したキーをクリックします。
  7. [キーを制限] をクリックし、[Maps SDK for Android] を選択してキーの使用を Android アプリに制限します。
  8. 生成された API キーをコピーします。「AIza"」で始まります。
  9. google_maps_api.xml ファイルで、YOUR_KEY_HERE と示されている google_maps_key 文字列にキーを貼り付けます。
  10. アプリを実行すると、オーストラリアのシドニーに設定されたマーカーで、アクティビティに埋め込まれた地図が表示されます。(シドニーのマーカーはテンプレートに含まれており、後で変更します)。

ステップ 3: mMap の名前を変更する

MapsActivity には GoogleMap 型の mMap というプライベート lateinit var があります。Kotlin の命名規則を遵守するには、mMap の名前を map に変更します。

  1. MapsActivity で、mMap を右クリックして [Refactor] > [Rename...] をクリックします

  1. 変数名を map に変更します。

onMapReady() 関数内の mMap へのすべての参照も map に変更されています。

Google マップには、標準、ハイブリッド、衛星、地形、および「なし」のマップタイプがあります(地図はまったく表示されません)。

標準のマップ

航空写真地図

ハイブリッド マップ

地形マップ

地図のタイプによって、表示される情報は異なります。たとえば、車でナビゲーションにマップを使用する場合は、道路名がわかると通常のオプションを使用できます。登山の際には、地形地図で頂上まで何歩登るかを決める必要があります。

このタスクでは、次のことを行います。

  1. ユーザーが地図の種類を変更できるオプション メニューのあるアプリバーを追加します。
  2. 地図の開始地点を自宅の位置に移動します。
  3. マップ上の単一の場所を示すマーカーのサポートを追加し、ラベルを含めることができるようになりました。

地図タイプのメニューを追加する

このステップでは、ユーザーが地図の種類を変更できるオプション メニューのあるアプリバーを追加します。

  1. 新しいメニュー XML ファイルを作成するには、res ディレクトリを右クリックして [New] > [Android Resource File] を選択します。
  2. ダイアログで、ファイルに map_options という名前を付けます。
  3. リソースタイプとして [Menu] を選択します。
  4. [OK] をクリックします。
  5. [Code] タブで、新しいファイルのコードを次のコードに置き換えて、マップのメニュー オプションを作成します。「なし」の場合、地図がまったく表示されないため、地図の種類を省略します。このステップではエラーが発生しますが、次のステップで解決します。
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto">
   <item
       android:id="@+id/normal_map"
       android:title="@string/normal_map"
       app:showAsAction="never" />
   <item
       android:id="@+id/hybrid_map"
       android:title="@string/hybrid_map"
       app:showAsAction="never" />
   <item
       android:id="@+id/satellite_map"
       android:title="@string/satellite_map"
       app:showAsAction="never" />
   <item
       android:id="@+id/terrain_map"
       android:title="@string/terrain_map"
       app:showAsAction="never" />
</menu>
  1. エラーを解決するために、strings.xmltitle 属性のリソースを追加します。
<resources>
   ...
   <string name="normal_map">Normal Map</string>
   <string name="hybrid_map">Hybrid Map</string>
   <string name="satellite_map">Satellite Map</string>
   <string name="terrain_map">Terrain Map</string>
   <string name="lat_long_snippet">Lat: %1$.5f, Long: %2$.5f</string>
   <string name="dropped_pin">Dropped Pin</string>
   <string name="poi">poi</string>
</resources>
  1. MapsActivityonCreateOptionsMenu() メソッドをオーバーライドし、map_options リソース ファイルからメニューをインフレートします。
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
   val inflater = menuInflater
   inflater.inflate(R.menu.map_options, menu)
   return true
}
  1. MapsActivity.ktonOptionsItemSelected() メソッドをオーバーライドします。地図タイプの定数を使用して地図の種類を変更し、ユーザーの選択を反映させます。
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
   // Change the map type based on the user's selection.
   R.id.normal_map -> {
       map.mapType = GoogleMap.MAP_TYPE_NORMAL
       true
   }
   R.id.hybrid_map -> {
       map.mapType = GoogleMap.MAP_TYPE_HYBRID
       true
   }
   R.id.satellite_map -> {
       map.mapType = GoogleMap.MAP_TYPE_SATELLITE
       true
   }
   R.id.terrain_map -> {
       map.mapType = GoogleMap.MAP_TYPE_TERRAIN
       true
   }
   else -> super.onOptionsItemSelected(item)
}
  1. アプリを実行します。
  2. [] をクリックして地図の種類を変更します。モードによって地図の外観がどのように変化するか注目してください。

デフォルトでは、onMapReady() コールバックには、Google マップが作成されたオーストラリアのシドニーにマーカーを配置するコードが含まれています。デフォルトのコールバックも、地図をアニメーション化してシドニーにパンします。

このタスクでは、マップのカメラを家に移動して、指定したレベルにズームし、そこにマーカーを配置します。

ステップ 1: 家にズームしてマーカーを追加する

  1. MapsActivity.kt ファイルで onMapReady() メソッドを見つけます。マーカーをシドニーに配置してカメラを移動するコードを削除します。メソッドは次のようになります。
override fun onMapReady(googleMap: GoogleMap) {
   map = googleMap

}
  1. こちらの手順で自宅の緯度と経度を確認します。
  2. 緯度と経度の値を作成し、浮動小数点値を入力します。
val latitude = 37.422160
val longitude = -122.084270
  1. homeLatLng という新しい LatLng オブジェクトを作成します。homeLatLng オブジェクトには、作成した値を渡します。
val homeLatLng = LatLng(latitude, longitude)
  1. 地図でズームインする方法の val を作成します。ズームレベル 15f を使用します。
val zoomLevel = 15f

ズームレベルは、地図でズームインする方法を制御します。次のリストは、各ズームレベルで表示される詳細レベルを示しています。

  • 1: 世界
  • 5: 大陸
  • 10: 都市
  • 15: 通り
  • 20: 建物
  1. カメラを homeLatLng に移動するには、map オブジェクトで moveCamera() 関数を呼び出し、CameraUpdateFactory.newLatLngZoom() を使用して CameraUpdate オブジェクトを渡します。homeLatLng オブジェクトと zoomLevel を渡します。
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
  1. homeLatLng の地図にマーカーを追加します。
map.addMarker(MarkerOptions().position(homeLatLng))

完成したメソッドは次のようになります。

override fun onMapReady(googleMap: GoogleMap) {
   map = googleMap

   //These coordinates represent the latitude and longitude of the Googleplex.
   val latitude = 37.422160
   val longitude = -122.084270
   val zoomLevel = 15f

   val homeLatLng = LatLng(latitude, longitude)
   map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
   map.addMarker(MarkerOptions().position(homeLatLng))
}
  1. アプリを実行します。地図が家にパンされ、目的のレベルにズームして、家にマーカーを配置します。

ステップ 2: ユーザーが長押しクリックでマーカーを追加できるようにする

このステップでは、ユーザーが地図上の場所を長押ししたときにマーカーを追加します。

  1. GoogleMap を引数として取る setMapLongClick() というメソッド スタブを MapsActivity に作成します。
  2. setOnMapLongClickListener リスナーを地図オブジェクトに追加します。
private fun setMapLongClick(map:GoogleMap) {
   map.setOnMapLongClickListener { }
}
  1. setOnMapLongClickListener()addMarker() メソッドを呼び出します。値が LatLng に設定された位置にある新しい MarkerOptions オブジェクトを渡します。
private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       map.addMarker(
           MarkerOptions()
               .position(latLng)
       )
   }
}
  1. onMapReady() メソッドの最後で、map を指定して setMapLongClick() を呼び出します。
override fun onMapReady(googleMap: GoogleMap) {
   ...
  
   setMapLongClick(map)
}
  1. アプリを実行します。
  2. 地図を長押しして、場所にマーカーを配置します。
  3. マーカーをタップして、画面の中央に表示します。

ステップ 3: マーカーの情報ウィンドウを追加する

このステップでは、マーカーがタップされたときにマーカーの座標を表示する InfoWindow を追加します。

  1. setMapLongClick()setOnMapLongClickListener() で、snippetval を作成します。スニペットは、タイトルの後ろに表示される追加のテキストです。スニペットにマーカーの緯度と経度が表示されます。
private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       // A snippet is additional text that's displayed after the title.
       val snippet = String.format(
           Locale.getDefault(),
           "Lat: %1$.5f, Long: %2$.5f",
           latLng.latitude,
           latLng.longitude
       )
       map.addMarker(
           MarkerOptions()
               .position(latLng)
       )
   }
}
  1. addMarker() で、R.string.dropped_pin 文字列リソースを使用して、マーカーの title をドロップピンに設定します。
  2. マーカーの snippetsnippet に設定します。

完成した関数は次のようになります。

private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       // A Snippet is Additional text that's displayed below the title.
       val snippet = String.format(
           Locale.getDefault(),
           "Lat: %1$.5f, Long: %2$.5f",
           latLng.latitude,
           latLng.longitude
       )
       map.addMarker(
           MarkerOptions()
               .position(latLng)
               .title(getString(R.string.dropped_pin))
               .snippet(snippet)
              
       )
   }
}
  1. アプリを実行します。
  2. 地図を長押しして、位置マーカーをドロップします。
  3. マーカーをタップして情報ウィンドウを表示します。

ステップ 4: スポット リスナーを追加する

スポット(地図上の場所)は、対応するアイコンとともに地図にデフォルトで表示されます。公園、学校、政府機関などもスポットに該当します。地図の種類を normal に設定すると、ビジネス スポットも地図に表示されます。ビジネス スポットは、店舗、レストラン、ホテルなどのビジネスを表します。

この手順では、地図に GoogleMap.OnPoiClickListener を追加します。このクリック リスナーは、ユーザーがスポットをクリックすると、地図上にマーカーを配置します。クリック リスナーには、スポット名を含む情報ウィンドウも表示されます。

  1. GoogleMap を引数として取る setPoiClick() というメソッド スタブを MapsActivity に作成します。
  2. setPoiClick() メソッドで、渡された GoogleMapOnPoiClickListener を設定します。
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->

   }
}
  1. setOnPoiClickListener() で、マーカーの val poiMarker を作成します。
  2. MarkerOptionsmap.addMarker() を使用してスポット名にマーカーを設定し、MarkerOptions を指定します。
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
   }
}
  1. setOnPoiClickListener() 関数で、poiMarker に対して showInfoWindow() を呼び出して、すぐに情報ウィンドウを表示します。
poiMarker.showInfoWindow()

setPoiClick() 関数の最終コードは次のようになります。

private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
       poiMarker.showInfoWindow()
   }
}
  1. onMapReady() の最後で setPoiClick() を呼び出し、map を渡します。
override fun onMapReady(googleMap: GoogleMap) {
   ...

   setPoiClick(map)
}
  1. アプリを実行して、公園やコーヒー ショップなどのスポットを見つけます。
  2. スポットをタップしてマーカーを配置し、スポット名を情報ウィンドウに表示します。

Google マップはさまざまな方法でカスタマイズできます。

他の XML 属性と同様に、他のフラグメントと同様に、MapFragment オブジェクトをカスタマイズできます。ただし、このステップでは、GoogleMap オブジェクトのメソッドを使用して、MapFragment のコンテンツの外観をカスタマイズします。

地図用にカスタマイズしたスタイルを作成するには、地図の対象物の表示方法を指定する JSON ファイルを生成します。この JSON ファイルを手動で作成する必要はありません。Google が提供する Maps Platform Styling Wizard を使用すると、地図のスタイルを設定した後に JSON が生成されます。このタスクでは、レトロなテーマで地図のスタイルを設定します。つまり、地図ではヴィンテージ色を使用し、色付きの道路を追加します。

ステップ 1: 地図のスタイルを作成する

  1. ブラウザで https://mapstyle.withgoogle.com/ に移動します。
  2. [スタイルの作成] を選択します。
  3. [Retro] を選択します。

  1. [その他のオプション] をクリックします。

  1. [対象物タイプ] リストで、[道路> 塗りつぶし] を選択します。
  2. 道路の色を選択した任意の色(ピンクなど)に変更します。

  1. [終了] をクリックします。

  1. 表示されたダイアログから JSON コードをコピーし、必要に応じて書式なしテキストのメモに保存して、次のステップで使用します。

ステップ 2: スタイルを地図に追加する

  1. Android Studio の res ディレクトリにリソース ディレクトリを作成し、raw という名前を付けます。JSON コードなどの raw ディレクトリ リソースを使用します。
  2. res/rawmap_style.json というファイルを作成します。
  3. 保存した JSON コードを新しいリソース ファイルに貼り付けます。
  4. MapsActivity で、onCreate() メソッドの上に TAG クラス変数を作成します。ロギングに使用されます。
private val TAG = MapsActivity::class.java.simpleName
  1. また、MapsActivity で、GoogleMap を受け取る setMapStyle() 関数を作成します。
  2. setMapStyle()try{} ブロックを追加します。
  3. スタイル設定の成功のために、try{} ブロックに val success を作成します。(次の catch ブロックを追加します)。
  4. try{} ブロックで、JSON スタイルを地図に設定し、GoogleMap オブジェクトで setMapStyle() を呼び出します。JSON ファイルを読み込む MapStyleOptions オブジェクトを渡します。
  5. 結果を success に割り当てます。setMapStyle() メソッドは、スタイル ファイルの解析とスタイル設定が成功したかどうかを示すブール値を返します。
private fun setMapStyle(map: GoogleMap) {
   try {
       // Customize the styling of the base map using a JSON object defined
       // in a raw resource file.
       val success = map.setMapStyle(
           MapStyleOptions.loadRawResourceStyle(
               this,
               R.raw.map_style
           )
       )
   }
}
  1. success の false である if ステートメントを追加します。スタイル設定に失敗した場合は、解析が失敗したログを出力します。
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
       if (!success) {
           Log.e(TAG, "Style parsing failed.")
       }
   }
}
  1. catch{} ブロックを追加して、スタイル ファイルが存在しない場合の処理を処理します。catch ブロックで、ファイルを読み込めない場合は Resources.NotFoundException をスローします。
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
   } catch (e: Resources.NotFoundException) {
       Log.e(TAG, "Can't find style. Error: ", e)
   }
}

完成したメソッドは次のコード スニペットのようになります。

private fun setMapStyle(map: GoogleMap) {
   try {
       // Customize the styling of the base map using a JSON object defined
       // in a raw resource file.
       val success = map.setMapStyle(
           MapStyleOptions.loadRawResourceStyle(
               this,
               R.raw.map_style
           )
       )

       if (!success) {
           Log.e(TAG, "Style parsing failed.")
       }
   } catch (e: Resources.NotFoundException) {
       Log.e(TAG, "Can't find style. Error: ", e)
   }
}
  1. 最後に、onMapReady() メソッドで setMapStyle() メソッドを呼び出し、GoogleMap オブジェクトを渡します。
override fun onMapReady(googleMap: GoogleMap) {
   ...
   setMapStyle(map)
}
  1. アプリを実行します。
  2. 地図を normal モードに設定すると、新しいスタイルがレトロなテーマと選択した色の道路とともに表示されます。

ステップ 3: マーカーのスタイルを設定する

地図上のマーカーのスタイルを設定することで、地図をさらにカスタマイズできます。このステップでは、デフォルトの赤いマーカーをよりグルービングに変更します。

  1. onMapLongClick() メソッドで、次のコードをコンストラクタの MarkerOptions() に追加して、デフォルトのマーカーを使用しますが、色は青色に変更します。
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))

onMapLongClickListener() は次のようになります。

map.setOnMapLongClickListener { latLng ->
   // A snippet is additional text that's displayed after the title.
   val snippet = String.format(
       Locale.getDefault(),
       "Lat: %1$.5f, Long: %2$.5f",
       latLng.latitude,
       latLng.longitude
   )
   map.addMarker(
       MarkerOptions()
           .position(latLng)
           .title(getString(R.string.dropped_pin))
           .snippet(snippet)
         .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
   )
}
  1. アプリを実行します。長押しすると表示されるマーカーが青に変わります。onPoiClick() メソッドにスタイルを追加していないため、スポット マーカーは赤色のままです。

Google マップの上にカスタマイズして描画することもできます。この手法は、人気の釣りスポットなど、特定の種類の場所を強調したい場合に便利です。

  • シェイプ: ポリラインポリゴンをマップに追加できます。
  • GroundOverlay オブジェクト: 地面オーバーレイは、地図に固定されている画像です。マーカーとは異なり、地面オーバーレイは画面ではなく地面の向きになります。地図を回転、傾斜、ズームすると、画像の向きが変わります。地面オーバーレイは、地図上のいずれかの領域に 1 つの画像を固定したい場合に役立ちます。

ステップ: 地面オーバーレイの追加

このタスクでは、Android の形状の地面オーバーレイを家の場所に追加します。

  1. この Android イメージをダウンロードして、res/drawable フォルダに保存します。(ファイル名が android.png であることを確認してください)。

  1. onMapReady() で、カメラを家の位置に移動するための呼び出しの後に、GroundOverlayOptions オブジェクトを作成します。
  2. オブジェクトを androidOverlay という変数に割り当てます。
val androidOverlay = GroundOverlayOptions()
  1. BitmapDescriptorFactory.fromResource() メソッドを使用して、ダウンロードした画像リソースから BitmapDescriptor オブジェクトを作成します。
  2. 結果の BitmapDescriptor オブジェクトを GroundOverlayOptions オブジェクトの image() メソッドに渡します。
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
  1. 目的のオーバーレイの幅(メートル単位)の float overlaySize を作成します。この例では、幅 100f が適しています。

position() メソッドを呼び出して GroundOverlayOptions オブジェクトの position プロパティを設定し、homeLatLng オブジェクトと overlaySize を渡します。

val overlaySize = 100f
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
   .position(homeLatLng, overlaySize)
  1. GoogleMap オブジェクトに対して addGroundOverlay() を呼び出し、GroundOverlayOptions オブジェクトを渡します。
map.addGroundOverlay(androidOverlay)
  1. アプリを実行します。
  2. Android イメージをオーバーレイとして表示するには、zoomLevel の値を 18f に変更します。

ユーザーは多くの場合、現在地を確認するために Google マップを使用します。地図上にデバイスの位置を表示するには、location-data レイヤを使用します。

位置情報レイヤは、地図に現在地を追加します。ユーザーがボタンをタップすると、デバイスの現在地が地図の中心に表示されます。現在地は、デバイスが静止している場合は青い点で表示され、デバイスが動いている場合は青い矢印で表示されます。

このタスクでは、位置情報レイヤを有効にします。

ステップ: 位置情報の利用許可をリクエストする

Google マップで位置情報のトラッキングを有効にするには、1 行のコードを入力します。ただし、ユーザーが実行時の権限モデルを使用して位置情報の利用許可を付与していることを確認してください。

このステップでは、位置情報の利用許可をリクエストし、位置情報の追跡を有効にします。

  1. AndroidManifest.xml ファイルで、FINE_LOCATION 権限がすでに存在することを確認します。Android Studio で Google マップのテンプレートが選択されたとき、この権限が挿入されました。
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  1. MapsActivityREQUEST_LOCATION_PERMISSION クラス変数を作成します。
private val REQUEST_LOCATION_PERMISSION = 1
  1. 権限が付与されているかどうかを確認するには、MapsActivityisPermissionGranted() というメソッドを作成します。このメソッドで、ユーザーが権限を付与したかどうかを確認します。
private fun isPermissionGranted() : Boolean {
  return ContextCompat.checkSelfPermission(
       this,
      Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
  1. アプリで位置情報のトラッキングを有効にするには、引数を取らず、何も返さない enableMyLocation() というメソッドを MapsActivity に作成します。内部で、ACCESS_FINE_LOCATION 権限を確認します。権限が付与されている場合は、位置情報レイヤを有効にします。それ以外の場合は、権限をリクエストします。
private fun enableMyLocation() {
   if (isPermissionGranted()) {
       map.isMyLocationEnabled = true 
   }
   else {
       ActivityCompat.requestPermissions(
           this,
           arrayOf<String>(Manifest.permission.ACCESS_FINE_LOCATION),
           REQUEST_LOCATION_PERMISSION
       )
   }
}
  1. onMapReady() コールバックから enableMyLocation() を呼び出して、位置情報レイヤを有効にします。
override fun onMapReady(googleMap: GoogleMap) {
   ...
   enableMyLocation()
}
  1. onRequestPermissionsResult() メソッドをオーバーライドします。requestCodeREQUEST_LOCATION_PERMISSION 権限と等しく、grantResults 配列が空でない場合、最初のスロットに PackageManager.PERMISSION_GRANTED があれば enableMyLocation() を呼び出します。
override fun onRequestPermissionsResult(
   requestCode: Int,
   permissions: Array<String>,
   grantResults: IntArray) {
   if (requestCode == REQUEST_LOCATION_PERMISSION) {
       if (grantResults.contains(PackageManager.PERMISSION_GRANTED)) {
           enableMyLocation()
       }
   }
}
  1. アプリを実行します。デバイスの位置情報へのアクセスをリクエストするダイアログが表示されます。許可してください。

デバイスの位置が青い点で示されます。位置情報ボタンが表示されています。現在地から地図を移動してこのボタンをクリックすると、地図がデバイスの現在地に戻ります。

完成した Codelab のコードをダウンロードします。

$  git clone https://github.com/googlecodelabs/android-kotlin-geo-maps


リポジトリを ZIP ファイルとしてダウンロードして解凍し、Android Studio で開くこともできます。

ZIP をダウンロード

  • Maps API を使用するには、Google API Console の API キーが必要です。
  • Android Studio では、Google マップ アクティビティ テンプレートを使用すると、アプリのレイアウト内に SupportMapFragment を 1 つ含む Activity が生成されます。また、このテンプレートは ACCESS_FINE_PERMISSION をアプリ マニフェストに追加し、アクティビティに OnMapReadyCallback を実装して、必要な onMapReady() メソッドをオーバーライドします。

実行時に GoogleMap のマップタイプを変更するには、GoogleMap.setMapType() メソッドを使用します。Google マップでは、次のいずれかのマップタイプを使用できます。

  • 標準: 通常の道路地図。道路、一部の人工物、河川などの重要な自然物を表示します。道路や対象物のラベルも表示されます。
  • ハイブリッド: 航空写真と道路地図を追加した写真。道路や対象物のラベルも表示されます。
  • 衛星: 写真データです。道路および対象物のラベルは表示されません。
  • 地形: 地形データ。色、等高線とラベル、透視投影による影も表示されます。一部の道路とラベルも表示されます。
  • なし: 基本地図タイルはありません。

Google マップについて:

  • マーカーは、特定の地域を示す指標です。
  • タップするとマーカーのデフォルトの動作として、場所に関する情報を含む情報ウィンドウが表示されます。
  • スポット(地図上の場所)は、対応するアイコンとともに基本地図にデフォルトで表示されます。公園、学校、政府機関などもスポットに該当します。
  • さらに、地図のタイプが normal の場合、ビジネス スポット(店舗、レストラン、ホテルなど)はデフォルトで地図に表示されます。
  • OnPoiClickListener を使用して、スポットに対するクリックを取得できます。
  • スタイル設定ウィザードを使用すると、Google マップのほぼすべての要素の外観を変更できます。スタイル設定ウィザードで生成される JSON ファイルでは、setMapStyle() メソッドを使用して Google マップに渡します。
  • マーカーをカスタマイズして、デフォルトの色を変更したり、デフォルトのマーカー アイコンをカスタム画像に置き換えたりすることができます。

その他の重要な情報:

  • 地面オーバーレイを使用して画像の位置を修正する。
  • GroundOverlayOptions オブジェクトを使用して、画像、画像のサイズ(メートル単位)、画像の位置を指定します。このオブジェクトを GoogleMap.addGroundOverlay() メソッドに渡して、地図にオーバーレイを設定します。
  • アプリに ACCESS_FINE_LOCATION 権限がある場合は、map.isMyLocationEnabled = true を設定して位置情報トラッキングを有効にできます。
  • この Codelab では説明していませんが、Google ストリートビューを使って特定の場所に関する補足情報を提供できます。これは、特定の場所のナビゲーション可能なパノラマ写真です。

Android デベロッパー ドキュメント:

リファレンス ドキュメント:

このコースの他の Codelab へのリンクについては、Kotlin での高度な Android Codelab のランディング ページをご覧ください。