【Jetpack Compose/Android】Maps Composeライブラリで地図アプリを実装する方法!
この記事からわかること
- Kotlin/Android Jetpack ComposeのMaps Composeの使い方
- Google Mapを表示させる方法
- 地図アプリの実装方法
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Narwhal Feature Drop
- Kotlin:2.1.10
- Material3
- AGP:8.9.2
- Gradle:8.11.1
- Maps Compose Library:6.10.0
- Mac M1:Sequoia 15.6.1
Jetpack Compose自体の基本的な使用方法に関しては以下の記事を参考にしてください。
Maps Compose Library
AndroidアプリかつJetpack ComposeでUIを実装している場合に地図を表示させたい場合は「Maps Compose Library」を使用します。Maps Compose Libraryは「Google Maps Android API(Maps SDK for Android)」をJetpack Composeで使えるように最適化したライブラリです。これまでのMapViewをViewとしてではなくComposable関数として地図を扱えるようになっています。
Google CloudからAPIキーの取得と設置
公式リファレンス:Maps SDK for Android のクイックスタート
「Maps SDK for Android」を使用するためには「Google Cloud」にアクセスして「Google Maps Platform」から「Maps SDK for Android」を有効化してGoogle Maps PlatformのAPIキーを取得する必要があります。
最初にGoogle Cloud上に対象のプロジェクトを作成していない場合は「Google Cloud」から作成しておいてください。
プロジェクトを作成したら左上のハンバーガーメニューから「Google Maps Platform」を選択sしてそのままクリックします。
すると連携する請求先アカウントを問われるので選択します。(Google Cloudに請求アカウントが未登録の場合は登録フローへ促されたような気がします)
「アカウントを設定」をクリックするとAPIキーが表示されます。ここで表示されたAPIキーがなぜか自分の環境では消失してしまい再度作成することになりましたが、本来なら後からでも参照できるはずです。「すべてのGoogle Maps APIを有効にします」にチェックを入れて先に進みます。
先ほど作成されたAPIキーの保護を促されますが、後でも設定できるので「後で」で終了します。(結局キーは再生成したのでここも不要でしたが)
生成されたキーに対して(私は消えていたので再度作成しました)有効にするAPIとアクセス制限を設けていきます。「Google Maps Platform」の左メニュー「鍵と認証情報」から「APIキー」セクションに生成されたキーがあるのでクリックします。(なければ上部の「認証情報を作成」からAPIキーを作成してください)
本番環境で使用するAPIキーには「アプリケーションの制限」をかけることが公式からも推奨されています。Androidアプリの場合はパッケージ名とリリースのフィンガープリントが必要になります。
不要なAPIにアクセスできないように「APIの制限」もかけておきます。今回は「Maps SDK for Android」だけ有効になるようにチェックを入れて保存しておきます。
肝心のAPIキーは「キーを表示します」からいつでも確認することができます。
AndroidアプリにAPIキーをセットする
取得したAPIキーはAndroidアプリの「AndroidManifest.xml」に設定します。APIキーは公開することは推奨されておらず悪用されるケースもあるのでベタがきではなく、secret.propertiesなどを用意してGitHubなどの管理対象からも外しておくようにしてください。
<manifest>
<application>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="YOUR_API_KEY_HERE"/>
</application>
</manifest>
ライブラリの導入
「Maps Compose Library」をプロジェクトに導入するために「build.gradle.kts」に以下を追加します。最新バージョンは公式を確認してください。
implementation("com.google.maps.android:maps-compose:6.10.0")
Composeで地図(Map)の実装
これでMaps Compose Libraryを使う準備が整ったので実際にJetpack Composeで地図を実装する方法を確認していきます。とはいえ実装はとても簡単でGoogleMapを使用するだけっで地図を表示させることが可能です。
@Composable
fun MapScreen() {
val skyTree = LatLng(35.710063, 139.8107)
// 地図の初期位置
val cameraPositionState = rememberCameraPositionState {
// zoom=15fで拡大して表示
position = CameraPosition.fromLatLngZoom(skyTree, 15f)
}
GoogleMap(
modifier = Modifier.fillMaxSize(),
cameraPositionState = cameraPositionState,
uiSettings = MapUiSettings(zoomControlsEnabled = false),
properties = MapProperties(mapType = MapType.NORMAL)
) {
// マーカーを追加
Marker(
state = MarkerState(position = skyTree),
title = "東京スカイツリー",
snippet = "東京都墨田区押上一丁目1番2号"
)
}
}
地図に関する細かい挙動は引数から色々制御することが可能です。
@Composable
public fun GoogleMap(
modifier: Modifier = Modifier,
// アクセシビリティ用。true にすると子ビューの説明文を親にマージする
mergeDescendants: Boolean = false,
// 地図のカメラ位置(緯度経度やズーム)の状態を管理するオブジェクト
// rememberCameraPositionState() を使うと状態が保持される
cameraPositionState: CameraPositionState = rememberCameraPositionState(),
// 地図全体のコンテンツ説明文(アクセシビリティ用)
contentDescription: String? = null,
// GoogleMap のオプションを生成するためのファクトリー関数
// 例: GoogleMapOptions().mapType(GoogleMap.MAP_TYPE_SATELLITE)
googleMapOptionsFactory: () -> GoogleMapOptions = { GoogleMapOptions() },
// 地図のプロパティ(地図タイプ、建物表示、トラフィック表示など)
properties: MapProperties = DefaultMapProperties,
// 位置情報を提供するカスタム LocationSource を指定可能
locationSource: LocationSource? = null,
// 地図の UI 設定(ズームコントロールやコンパス表示など)
uiSettings: MapUiSettings = DefaultMapUiSettings,
// 室内地図の階層が変わったときに呼ばれるリスナー
indoorStateChangeListener: IndoorStateChangeListener = DefaultIndoorStateChangeListener,
// 地図がタップされたときのコールバック
onMapClick: ((LatLng) -> Unit)? = null,
// 地図が長押しされたときのコールバック
onMapLongClick: ((LatLng) -> Unit)? = null,
// 地図の描画が完了したときに呼ばれるコールバック
onMapLoaded: (() -> Unit)? = null,
// 「現在地」ボタンが押されたときのコールバック(true を返すとデフォルト動作をキャンセル)
onMyLocationButtonClick: (() -> Boolean)? = null,
// ユーザーの現在地がタップされたときのコールバック
onMyLocationClick: ((Location) -> Unit)? = null,
// POI(Point of Interest, 施設やランドマーク)がタップされたときのコールバック
onPOIClick: ((PointOfInterest) -> Unit)? = null,
// 地図コンテンツの余白を指定(ボタンなどがかぶらないように調整する)
contentPadding: PaddingValues = DefaultMapContentPadding,
// ダークモードやライトモードなどの地図カラースキームを指定可能
mapColorScheme: ComposeMapColorScheme? = null,
// MapView を生成するためのファクトリー(通常はデフォルトの ::MapView でOK)
mapViewFactory: (Context, GoogleMapOptions) -> MapView = ::MapView,
// 地図上に Composable を追加できるスロット(Marker や Circle などを描画する)
content: @Composable @GoogleMapComposable () -> Unit = {},
)
MapUiSettings:地図のUI設定を行う
引数uiSettingsにはMapUiSettings型で地図上のUI設定を行うことが可能です。地図UIのジェスチャー周りの挙動やサイドに表示される「現在値ボタン」などの表示 / 非表示を切り替えることが可能です。
public class MapUiSettings(
// 北以外を向いたときに表示されるコンパスを有効化するか
public val compassEnabled: Boolean = true,
// インドアマップ用の階層切り替えコントロールを表示するか
public val indoorLevelPickerEnabled: Boolean = true,
// 右下に表示されるツールバー(Google マップアプリへのショートカット)を表示するか
public val mapToolbarEnabled: Boolean = true,
// 現在地ボタンを表示するか
public val myLocationButtonEnabled: Boolean = true,
// 二本指での地図回転を有効化するか
public val rotationGesturesEnabled: Boolean = true,
// ドラッグによる地図の移動を有効化するか
public val scrollGesturesEnabled: Boolean = true,
// 回転/ズーム中のスクロールを許可するか
public val scrollGesturesEnabledDuringRotateOrZoom: Boolean = true,
// 二本指での傾き操作を有効化するか
public val tiltGesturesEnabled: Boolean = true,
// 右下に表示される「+ / -」のズームボタンを有効化するか
public val zoomControlsEnabled: Boolean = true,
// ピンチ操作でのズームを有効化するか
public val zoomGesturesEnabled: Boolean = true,
)
MapProperties:地図の表示や状態設定
引数propertiesにはMapProperties型で地図の表示や状態設定を行うことが可能です。地図自体の表示方法の変更や交通情報などを表示させることができるようになります。
public class MapProperties(
// 建物の 3D 表示を有効化するか
public val isBuildingEnabled: Boolean = false,
// インドアマップ(建物内部の階層)を表示するか
public val isIndoorEnabled: Boolean = false,
// 現在地レイヤー(青い点)を表示するか
public val isMyLocationEnabled: Boolean = false,
// 交通情報を表示するか
public val isTrafficEnabled: Boolean = false,
// カメラ移動を制限する範囲
public val latLngBoundsForCameraTarget: LatLngBounds? = null,
// JSON 定義によるカスタムスタイルを適用(夜間モードなど)
public val mapStyleOptions: MapStyleOptions? = null,
// 地図の種類を指定:NONE, NORMAL, SATELLITE(航空写真), TERRAIN(地形), HYBRID(航空写真 + 道路や地名ラベルを重ね合わせた表示)
public val mapType: MapType = MapType.NORMAL,
// 最大ズームレベル制限
public val maxZoomPreference: Float = 21.0f,
// 最小ズームレベル制限
public val minZoomPreference: Float = 3.0f,
)
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。






