Kakap map jetpack compose

[FAQ] 지도/로컬 API 문의 전 꼭 읽어 주세요.
https://devtalk.kakao.com/t/faq-api/125610

아래 코드와 같이 화면을 구현해 보았으나, 화면에 지도가 표시 되지 않습니다. 무엇을 더 확인 해야 할까요???

@Composable
fun KakaoMapView(viewModel: MainViewModel = koinViewModel()) {

val context = LocalContext.current
val mapView = rememberMapView(context = context)

var _lat = viewModel.lat.observeAsState(0.0)
var _lon = viewModel.lon.observeAsState(0.0)
var lat = _lat.value
var lon = _lon.value

Column ( modifier = Modifier.fillMaxSize()){
    Row( modifier = Modifier.fillMaxSize()) {
        IconButton( onClick = {
            viewModel.setLocation(context)
        }) {
            Icon(Icons.Default.MyLocation, contentDescription = "Search My Location")
        }
    }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .padding(3.dp)
    ) {
        AndroidView(
            factory = {
                mapView
            },
        )
    }
}

}

@Composable
fun rememberMapView(
context: Context,
): MapView {
val mapView = remember {
MapView(context).also { mapView →
mapView.start(
object : MapLifeCycleCallback() {
override fun onMapDestroy() = Unit
override fun onMapError(e: Exception?) = Unit
override fun onMapResumed() = Unit
},

            object : KakaoMapReadyCallback() {
                override fun onMapReady(map: KakaoMap) = Unit
            }
        )
    }
}

return mapView

}

--------------------실행시 로그 ----
---------------------------- PROCESS ENDED (24890) for package com.example.pill2024 ----------------------------
---------------------------- PROCESS STARTED (29255) for package com.example.pill2024 ----------------------------
00:38:19.162 D —> RequestHeader(https://dapi.kakao.com/v2/maps/vector/auth) {Accept=[application/json], Authorization=[KakaoAK 9ec46f9124e7e98961a25530bc05c447], KA=[mapSdk/2.12.8 os/android-34 lang/ko-KR origin/cLtWB/yTFq5QbK1WamQnRbOVofI= device/SM-S918N android_pkg/com.example.pill2024]}
00:38:19.433 V ← {null=[HTTP/1.1 200 OK], Connection=[keep-alive], Content-Length=[0], Date=[Tue, 29 Oct 2024 15:38:19 GMT], strict-transport-security=[max-age=31536000; includeSubDomains], X-Android-Received-Millis=[1730216299433], X-Android-Response-Source=[NETWORK 200], X-Android-Selected-Protocol=[http/1.1], X-Android-Sent-Millis=[1730216299365], X-Request-Id=[28033a0c521984316fda2c8c9afa0974]}

화면이 나타나지 않습니다. 다른 걸 수정해야 할까요???

  1. 위에 올려주신 로그가 지도를 실행했을 때 나오는 로그의 전부인가요?

  2. 지도를 실행했을 때, onMapReady() 함수로 호출이 불리는가요?

  3. 지도가 어떤 상태로 안나오는지 확인을 위해, 지도가 안나오는 부분에 대한 캡쳐화면 첨부 부탁 드립니다.

  1. 로그는 K3f 로 필터링 했습니다.

10:48:39.622 D —> RequestHeader(https://dapi.kakao.com/v2/maps/vector/auth) {Accept=[application/json], Authorization=[KakaoAK 9ec46f9124e7e98961a25530bc05c447], KA=[mapSdk/2.12.8 os/android-34 lang/ko-KR origin/cLtWB/yTFq5QbK1WamQnRbOVofI= device/SM-S918N android_pkg/com.example.pill2024]}
10:48:40.012 V ← {null=[HTTP/1.1 200 OK], Connection=[keep-alive], Content-Length=[0], Date=[Wed, 30 Oct 2024 01:48:39 GMT], strict-transport-security=[max-age=31536000; includeSubDomains], X-Android-Received-Millis=[1730252920011], X-Android-Response-Source=[NETWORK 200], X-Android-Selected-Protocol=[http/1.1], X-Android-Sent-Millis=[1730252919913], X-Request-Id=[7223dddbdb8e584aa35e72b17c5d352f]}
10:49:02.544 D onDetachedFromWindow(isFinishing=false)
10:49:02.659 D —> RequestHeader(https://dapi.kakao.com/v2/maps/vector/auth) {Accept=[application/json], Authorization=[KakaoAK 9ec46f9124e7e98961a25530bc05c447], KA=[mapSdk/2.12.8 os/android-34 lang/ko-KR origin/cLtWB/yTFq5QbK1WamQnRbOVofI= device/SM-S918N android_pkg/com.example.pill2024]}
10:49:02.718 V ← {null=[HTTP/1.1 200 OK], Connection=[keep-alive], Content-Length=[0], Date=[Wed, 30 Oct 2024 01:49:02 GMT], strict-transport-security=[max-age=31536000; includeSubDomains], X-Android-Received-Millis=[1730252942717], X-Android-Response-Source=[NETWORK 200], X-Android-Selected-Protocol=[http/1.1], X-Android-Sent-Millis=[1730252942662], X-Request-Id=[52f3f8744bccf6a283bdd0a6ac70a9d8]}

  1. 무슨 말씀 일까요???
    다른 질의 내용에 있는 코드을 옮겨서 해 보는 중입니다.

  2. 이미지는 첨부해 보겠습니다.

  3. 앱 등록할 때 혹시 package 이름을 변경해서 다시 등록하였을 때 문제가 될까요?

올려주신 로그를 보니, 인증을 시도한 로그만 있고 중간에 onDetachedFromWindow() 가 불리면서 MapView 자체가 뷰 구조에서 없어진걸로 보여집니다. MapView 가 제대로 표시되고 있는게 맞는지 확인 부탁드립니다.

(작성자가 삭제한 게시물)

음 … 예제 소스 코드을 다시 복사해서 map 은 그려 집니다.

다음 궁금한 것은 위에 코드와 같이 해서 지도을 그린 다음… camera 위치를 조정 하는 방법은 어떻게 될까요???
아래 코드 처럼 onMapReady 함수을 밖으로 호출 하게 해서 해 보아도 잘 안 되네요.

미리 감사드립니다.

import android.content.Context
import android.util.Log
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.MyLocation
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocal
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import com.example.pill2024.viewModels.MainViewModel
import com.kakao.vectormap.KakaoMap
import com.kakao.vectormap.KakaoMapReadyCallback
import com.kakao.vectormap.LatLng

import com.kakao.vectormap.MapLifeCycleCallback
import com.kakao.vectormap.MapView
import com.kakao.vectormap.camera.CameraPosition
import com.kakao.vectormap.camera.CameraUpdate
import com.kakao.vectormap.camera.CameraUpdateFactory
import com.ramcosta.composedestinations.annotation.Destination
import org.koin.androidx.compose.koinViewModel
import kotlin.also

@Destination
@Composable
fun KakaoMap(
viewModel: MainViewModel = koinViewModel()
) {
val context = LocalContext.current
var _lat = viewModel.lat.observeAsState(0.0)
var _lon = viewModel.lon.observeAsState(0.0)
var lat = _lat.value
var lon = _lon.value
val mapView = rememberMapView(context = context, onMapReady = {
viewModel.setLocation(context)
Log.e(“”,“onMapReady … lat/lon: ${lat} ${lon}”)
val latLon = LatLng.from(lat, lon)
val cameraUpdate = CameraUpdateFactory.newCenterPosition(latLon, 10)
it.moveCamera(cameraUpdate)
})

Column ( modifier = Modifier.fillMaxSize()) {
    Row(modifier = Modifier.fillMaxWidth()) {
        IconButton(onClick = {
            viewModel.setLocation(context)
        }) {
            Icon(Icons.Default.MyLocation, contentDescription = "Search My Location")
        }
    }
    Box(
        modifier = Modifier
            .fillMaxSize()
            .padding(3.dp)
    ) {
        AndroidView(
            factory = {
                mapView
            },
        )
    }
}

}

@Composable
fun rememberMapView(
context: Context,
onMapReady: (KakaoMap) → Unit
): MapView {
val mapView = remember {
MapView(context).also { mapView →
mapView.start(
object : MapLifeCycleCallback() {
override fun onMapDestroy() = Unit
override fun onMapError(e: Exception?) = Unit
override fun onMapResumed() = Unit
},

            object : KakaoMapReadyCallback() {
                override fun onMapReady(map: KakaoMap) {
                    onMapReady(map)
                }
            }
        )
    }
}

return mapView

}

우선 위에 올려주신 코드만 놓고 보면, onMapReady() 함수는 정상적으로 실행이 되시나요? (로그가 잘 찍힘 등)

그렇다면, 아래의 코드가 원하는 위치로 카메라 이동이 안된다는 질문이실 거 같은데, 좌표가 잘 들어갔는지 Log.e(“”,“onMapReady … lat/lon: ${lat} ${lon}”) 으로 로그를 찍으셨던 좌표값 공유 부탁 드립니다.

val cameraUpdate = CameraUpdateFactory.newCenterPosition(latLon, 10)
it.moveCamera(cameraUpdate)

저것이 onMapready 상태 일 때는 좌표가 0.0, 0.0 이였는 데, gps 수신 되고 나면 37.5236062 126.8916459 이 되는 데…
아마도 이때는 onMapReady 가 끝난 상태 일 겁니다.

그럼 그 이후에는 카메라 이동을 할 수 없을 까요???

onMapReady() 호출이 불리곤 난 후에는, onMapReady 의 파라미터로 들어온 KakaoMap 객체를 가지고 카메라 관련 함수를 호출하시면 되십니다. 즉, gps 수신 되고 나서 제대로 된 좌표가 들어오면 그때 카메라 함수를 호출하시면 되십니다.

말씀하신 대로 onMapReady() 일 때는 좌표가 0.0, 0.0 이라서, 지도 이동이 제대로 안된 것 같습니다.