📱 안드로이드 Android ~ Kotlin

[Android/Kotlin] Google Maps API 사용해서 지도 표시하기

핑크빛연어 2023. 1. 10. 20:38

 

안녕하세요! 벌써 2023년 새해!!!!!🪅 새해 복 많이 받으세요🙈

오랜만에 올려보는 포스팅입니다🥹

 

Google Maps API 를 사용해서 Android 에 지도를 표시하고📍 현재 위치를 가져오는 방법에 대해 포스팅해보겠습니다 🗺

 

먼저 Google 클라우드 플랫폼에서 프로젝트를 만들어 설정을 해주고,

Android Studio 에서 라이브러리 추가 후 소스코드 작성을 해줍니다.

 

 

🚨 Google 클라우드 플랫폼에서 프로젝트 추가 및 설정

 

Google 클라우드 플랫폼에서 프로젝트를 만들어야 합니다. 아래 사이트로 들어가서 로그인해주세요~

https://console.developers.google.com/apis/dashboard

 

Google 클라우드 플랫폼

로그인 Google 클라우드 플랫폼으로 이동

accounts.google.com

 

 

Google Cloud 타이틀 옆 프로젝트 이름 클릭해서 새 프로젝트 를 클릭하여 새로운 프로젝트를 생성합니다.

 

 

프로젝트 이름과 위치를 작성 후 만들기 버튼을 클릭합니다.

 

 

프로젝트가 생성되었다면 API 및 서비스 > 라이브러리 메뉴로 들어갑니다.

 

 

안드로이드에서 Google 지도 사용을 위해 Maps SDK for Android 클릭해서

 

 

Maps SDK for Android 사용 버튼 클릭합니다.

 

 

이제 API 및 서비스 > 사용자 인증 정보 메뉴로 들어갑니다.

 

 

사용자 인증 정보 만들기 버튼을 클릭해서 만들도록 합니다!

 

 

API 키에 대한 설정을 해주고 저장 버튼을 클릭합니다.

애플리케이션 제한사항으로 저는 안드로이드 앱에서 사용할 것이기 때문에 Android 앱을 선택해주었어요!

Android 앱의 사용량 제한 에는 +ADD 버튼을 클릭하여 특정 프로젝트를 추가할 수 있습니다.

패키지명SHA-1 디지털 지문을 넣어주여어야 해요.

 

 

 

🚨 Android Studio 라이브러리 추가 및 소스코드 작성

 

이제 안드로이드 스튜디오로 가줍니다.

Google Maps 를 사용하기 위해 Google Play services 라이브러리를 설치해주어야 합니다.

상단 메뉴바의 Tools > SDK Manager 로 들어와서 SDK Tools 탭에서 Google Play services 체크 후 Apply, OK 버튼을 클릭하여 설치 후 적용해줍니다.

 

 

1. build.gradle(:app)

dependencies 안에 Google Map Service 와 Google Location Service 에 대한 의존성을 추가해줍니다.

dependencies {

...

    // Google Map
    implementation 'com.google.android.gms:play-services-maps:17.0.0'
    implementation 'com.google.android.gms:play-services-location:17.0.0'
    
...

}

 

2. AndroidManifest.xml

application 안에 meta-data 태그로 Google API 키를 넣어줍니다.

<manifest
	<application
		...

		<meta-data
    		android:name="com.google.android.geo.API_KEY"
        	android:value="API키" />
        
		...
	</application>
</manifest>

 

3. activity_map.xml

MapView 를 사용해서 구성해줍니다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.google.android.gms.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

 

4. MapActivity.kt

Activity 에 OnMapReadyCallback 을 implement 하고,

onMapReady() 를 override 해줍니다. Map 이 사용할 준비가 되었을 때 onMapReady() 호출되는 메소드입니다.

onCreate() 에서 getMapAsync(this) 를 호출해서 GoogleMap 객체가 준비될 때 실행될 콜백을 등록합니다. 

 

googleMap 의 지도 유형(googleMap.mapType) 을 설정해줄 수 있습니다.

  • MAP_TYPE_NORMAL : 일반 도로 지도, 도로 등의 중요한 특징들이 표시된 지도

  • MAP_TYPE_HYBRID : 도로 지도와 위성사진 데이터가 동시 표시된 지도

  • MAP_TYPE_SATELLITE : 위성사진 데이터로 도로 및 특징이 표시된 지도 (대한민국은 위성지도 사용제한)

  • MAP_TYPE_TERRAIN : 지형도 데이터로 색상, 등고선 및 원근 음영이 표시된 지도

 

그리고 MapView 를 사용할 때 Activity 의 라이프사이클에 맞춰 MapView 가 포함된 

onStart(), onStop(), onResume(), onPause(), onLowMemory(), onDestroy(), onSaveInstanceState()

호출해야 합니다. 그렇지 않으면 지도가 표시되지 않습니다! 주의하세요~

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.eun.gugujeoljeol.ggjj.aos.databinding.ActivityMapBinding

import com.google.android.gms.maps.*
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.Marker
import com.google.android.gms.maps.model.MarkerOptions

internal class MapActivity : AppCompatActivity(), OnMapReadyCallback {

    companion object {
        const val TAG = "MapActivity"
    }

    lateinit var binding: ActivityMapBinding

    private lateinit var mapView: MapView
    private lateinit var googleMap: GoogleMap
    private var currentMarker: Marker? = null


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMapBinding.inflate(layoutInflater)
        setContentView(binding.root)

        this.mapView = binding.mapView
        mapView.onCreate(savedInstanceState)
        mapView.getMapAsync(this@MapActivity)

    }


    /**
     * onMapReady()
     * Map 이 사용할 준비가 되었을 때 호출
     * @param googleMap
     */
    override fun onMapReady(googleMap: GoogleMap) {
        this.googleMap = googleMap

        currentMarker = setupMarker(LatLngEntity(37.5562,126.9724))  // default 서울역
        currentMarker?.showInfoWindow()
    }


    /**
     * setupMarker()
     * 선택한 위치의 marker 표시
     * @param locationLatLngEntity
     * @return
     */
    private fun setupMarker(locationLatLngEntity: LatLngEntity): Marker? {

        val positionLatLng = LatLng(locationLatLngEntity.latitude!!,locationLatLngEntity.longitude!!)
        val markerOption = MarkerOptions().apply {
            position(positionLatLng)
            title("위치")
            snippet("서울역 위치")
        }

        googleMap.mapType = GoogleMap.MAP_TYPE_NORMAL  // 지도 유형 설정
        googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(positionLatLng, 15f))  // 카메라 이동
        googleMap.animateCamera(CameraUpdateFactory.zoomTo(15f))  // 줌의 정도 - 1 일 경우 세계지도 수준, 숫자가 커질 수록 상세지도가 표시됨
        return googleMap.addMarker(markerOption)

    }


    override fun onStart() {
        super.onStart()
        mapView.onStart()
    }
    override fun onStop() {
        super.onStop()
        mapView.onStop()
    }
    override fun onResume() {
        super.onResume()
        mapView.onResume()
    }
    override fun onPause() {
        super.onPause()
        mapView.onPause()
    }
    override fun onLowMemory() {
        super.onLowMemory()
        mapView.onLowMemory()
    }
    override fun onDestroy() {
        mapView.onDestroy()
        super.onDestroy()
    }


    /**
     * LatLngEntity data class
     *
     * @property latitude 위도 (ex. 37.5562)
     * @property longitude 경도 (ex. 126.9724)
     */
    data class LatLngEntity(
        var latitude: Double?,
        var longitude: Double?
    )

}

 

 

 

결과 화면

 

 

감사합니당 🤗

 

728x90
반응형