[Jetpack Compose] GoogleMapsを表示する

APIKeyの取得

GCP (Google Cloud Platform)でMaps SDK for AndroidターゲットのKeyを発行する (iOSも任意で)

API Keyをメモしておく。

実装

build.gradle (モジュール)

以下をdependenciesに追加、バージョンは動くものを。

implementation("com.google.maps.android:maps-compose:4.3.1")
implementation("com.google.android.gms:play-services-maps:18.2.0")
implementation("com.google.accompanist:accompanist-permissions:0.34.0")

AndroidManifest.xml

ネットワーク接続、位置情報許可を求めるので以下を追加

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

またAPIKeyをプロジェクトに読み込むため、applicationタグ内に以下を追加。

ハードコーディングしたキーをそのままPushするとセキュリティ的によろしくないのでそちらはお気をつけて。

<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="ここにAPIKey" />

MainActivity.kt

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            MyMapsTheme {
                MyMapsApp()
            }
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MyMapsApp() {
    Scaffold(
        topBar = {
            CenterAlignedTopAppBar(title = { Text("Google Maps Demo") })
        }
    ) { paddingValues ->
        GoogleMapsScreen(modifier = Modifier.padding(paddingValues))
    }
}

@OptIn(ExperimentalPermissionsApi::class, ExperimentalPermissionsApi::class)
@Composable
fun GoogleMapsScreen(modifier: Modifier = Modifier) {
    val bathurstStation = LatLng(43.6669, -79.4116) // 好きな座標を
    val cameraPositionState = rememberCameraPositionState {
        position = CameraPosition.fromLatLngZoom(bathurstStation, 15f)
    }

    // 位置情報パーミッションの状態を管理
    val locationPermissionsState = rememberMultiplePermissionsState(
        permissions = listOf(
            android.Manifest.permission.ACCESS_FINE_LOCATION,
            android.Manifest.permission.ACCESS_COARSE_LOCATION
        )
    )

    // ユーザーがパーミッションを許可しているかどうか
    val hasLocationPermission = locationPermissionsState.allPermissionsGranted

    Column(
        modifier = modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        if (hasLocationPermission) {
            // パーミッションが許可されている場合のみマップを表示
            GoogleMap(
                modifier = Modifier.fillMaxSize(),
                cameraPositionState = cameraPositionState,
                properties = MapProperties(isMyLocationEnabled = true), // 現在地取得
                uiSettings = MapUiSettings(zoomControlsEnabled = true) // ズーム
            ) {
                // マーカー、ポリラインなど追加可能
            }
        } else {
            // パーミッションが許可されていない場合、説明と要求ボタンを表示
            Text(
                text = "現在地を表示するには位置情報パーミッションが必要です。",
                fontSize = 20.sp,
                modifier = Modifier.padding(16.dp)
            )
            Spacer(modifier = Modifier.height(16.dp))
            Button(onClick = {
                // パーミッションを要求する
                locationPermissionsState.launchMultiplePermissionRequest()
            }) {
                Text("パーミッションを許可する")
            }
        }
    }
}


@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    MyMapsTheme {
        GoogleMapsScreen()
    }
}