구글맵 예제

jericho·2024년 1월 24일

Android

목록 보기
4/15

console.cloud.google.com에서 API 키를 발급받아야 하고, 라이브러리에서 Maps SDK for Android 를 사용 설정해야 한다.

// 그래들
implementation("com.google.android.gms:play-services-maps:18.2.0")
implementation("com.google.android.gms:play-services-location:21.0.1")

// 매니페스트 - 최상단 (어플리케이션 위)
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />

// 애플리케이션 하위 최상단
<uses-library
    android:name="org.apache.http.legacy"
    android:required="true" />

<meta-data
    android:name="com.google.android.maps.v2.API_KEY"
    android:value="APIKEYHERE" />
<meta-data
    android:name="com.google.android.gms.version"
    android:value="@integer/google_play_services_version" />

// FragmentContainerView 혹은 fragment의 속성에
android:name="com.google.android.gms.maps.SupportMapFragment"

// 액티비티에
// OnMapReadyCallback 인터페이스 상속
private var googleMap: GoogleMap? = null

/*
getMapAsync는 OnMapReadyCallback 인터페이스를 파라미터로 받는데,
이 인터페이스의 onMapReady 메서드는 Google Map 객체가 준비되었을 때 호출된다.
즉, getMapAsync(this) 코드는 Google Map이 완전히 로드되었을 때
this 객체(즉, OnMapReadyCallback 인터페이스를 구현한 객체)의 onMapReady() 메서드를 호출하도록 지시한다.
따라서, 이 코드는 Google Map이 준비되면 this 객체의 onMapReady() 메서드를 호출하라는 의미이다.
onMapReady() 메서드 내에서는 Map 객체를 사용하여 원하는 동작(예: 마커 추가, 카메라 이동 등)을 수행할 수 있다.
 */
/** 권한 물어보고 프래그먼트에 지도 연결 */
private val locationPermissionsLauncher = registerForActivityResult(
    ActivityResultContracts.RequestMultiplePermissions()
) { results ->
    if (results.all { it.value }) {
        (supportFragmentManager.findFragmentById(binding.fcv1.id) as SupportMapFragment)
            .getMapAsync(this)  // 실패하면 터뜨려서 디버깅하게 엘비스 다 빼버림
    } else {  //문제가 발생했을 때
        Toast.makeText(this, "권한 승인이 필요합니다.", Toast.LENGTH_LONG).show()
    }
}

/** 위치 서비스가 gps를 사용해서 위치를 확인 */
private lateinit var fusedLocationClient: FusedLocationProviderClient

// onCreate에
locationPermissionsLauncher.launch(
    arrayOf(
        Manifest.permission.ACCESS_COARSE_LOCATION,
        Manifest.permission.ACCESS_FINE_LOCATION
    )
)

// 아래에 함수 쭉
override fun onMapReady(p0: GoogleMap) {
    googleMap = p0
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
//    googleMap.mapType = GoogleMap.MAP_TYPE_HYBRID  // default 노말 생략 가능
    updateLocation()

    // 서울 시청 마커 추가해보기
    googleMap!!.addMarker(MarkerOptions().also {
        it.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
        it.position(LatLng(37.566610, 126.978403))
        it.title("서울시청")
        it.snippet("Tel:01-120")
    })
}

private fun updateLocation() {
    //권한 처리
    if (ActivityCompat
            .checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
        != PackageManager.PERMISSION_GRANTED
        && ActivityCompat
            .checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
        != PackageManager.PERMISSION_GRANTED
    ) return

    val locationRequest = LocationRequest.create().also {
        it.interval = 1000L
        it.fastestInterval = 500L
        it.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    }

    /** 위치 값 요청에 대한 갱신 정보를 받는 변수 */
    val locationCallback = object : LocationCallback() {
        //1초에 한번씩 변경된 위치 정보가 onLocationResult 으로 전달된다.
        override fun onLocationResult(locationResult: LocationResult) {
            for (location in locationResult.locations) {
                Log.d("위치정보", "위도: ${location.latitude} 경도: ${location.longitude}")
                setLastLocation(location)  //계속 실시간으로 위치를 받아오고 있기 때문에 맵을 확대해도 다시 줄어든다
            }
        }
    }

    // 위에 만든 locationRequest랑 locationCallback을 등록?하는듯.
    fusedLocationClient
        .requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper()!!)
}

/** 확인을 위해 현재 위치에 계속해서 마커를 찍고 보여주는 코드 */
fun setLastLocation(lastLocation: Location) {
    val latLng = LatLng(lastLocation.latitude, lastLocation.longitude)

    val markerOptions = MarkerOptions().position(latLng).title("나 여기 있어용~")
    val cameraPosition = CameraPosition.Builder().target(latLng).zoom(15.0f).build()

    googleMap?.addMarker(markerOptions)
    googleMap?.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
}

0개의 댓글