반응형
📍 Android에서 Kakao 로컬 API로 주소/좌표 변환하기

이 글에서는 안드로이드 앱에서 Kakao REST API를 사용하여 좌표 → 주소 변환, 주소 → 좌표 변환을 구현하는 방법을 설명합니다.
초보 개발자도 쉽게 따라 할 수 있도록 Retrofit2 + Coroutine + ViewModel 기반으로 단계별로 안내합니다.
✅ 1. 사전 준비
1.1. Kakao REST API 키 발급
- 카카오 개발자 사이트에 로그인
- 애플리케이션 등록 → 앱 키 → REST API 키 복사
- Android 플랫폼 등록 → 패키지명 + 키 해시 입력 (중요!)
1.2. Android 권한 설정
AndroidManifest.xml에 다음 권한을 추가하세요.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
위치 권한은 런타임 요청이 필요합니다 (Activity나 Composable에서).
---
✅ 2. Gradle 설정
build.gradle (Module) 파일에 다음을 추가하세요.
dependencies {
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
implementation "com.squareup.okhttp3:logging-interceptor:4.12.0"
}
---
✅ 3. Retrofit 구성
3.1. 데이터 클래스
data class KakaoAddressResponse(
val documents: List<Document>,
val meta: Meta
)
data class Meta(
val is_end: Boolean,
val pageable_count: Int,
val total_count: Int
)
data class Document(
val address: Address,
val address_name: String,
val address_type: String,
val road_address: RoadAddress,
val x: String,
val y: String
)
data class Address(
val address_name: String,
val b_code: String,
val h_code: String,
val main_address_no: String,
val mountain_yn: String,
val region_1depth_name: String,
val region_2depth_name: String,
val region_3depth_h_name: String,
val region_3depth_name: String,
val sub_address_no: String,
val x: String,
val y: String
)
data class RoadAddress(
val address_name: String,
val building_name: String,
val main_building_no: String,
val region_1depth_name: String,
val region_2depth_name: String,
val region_3depth_name: String,
val road_name: String,
val sub_building_no: String,
val underground_yn: String,
val x: String,
val y: String,
val zone_no: String
)
3.2. Retrofit 인터페이스
interface KakaoApiService {
@GET("v2/local/geo/coord2address.json")
suspend fun getAddressFromCoords(
@Header("Authorization") authorization: String,
@Query("x") longitude: Double,
@Query("y") latitude: Double
): KakaoAddressResponse
@GET("v2/local/search/address.json")
suspend fun getCoordsFromAddress(
@Header("Authorization") authorization: String,
@Query("query") query: String
): KakaoAddressResponse
}
3.3. Retrofit 클라이언트
object KakaoApiClient {
private const val BASE_URL = "https://dapi.kakao.com/"
private val logging = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
private val client = OkHttpClient.Builder()
.addInterceptor(logging)
.build()
val apiService: KakaoApiService by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(KakaoApiService::class.java)
}
}
---
✅ 4. ViewModel + Coroutine 통합
Coroutine을 사용하여 API를 호출하고, StateFlow로 결과를 UI에 전달합니다.
class LocationViewModel : ViewModel() {
private val _address = MutableStateFlow<String?>(null)
val address: StateFlow<String?> = _address
private val apiKey = "KakaoAK YOUR_REST_API_KEY" // <-- 실제 키로 교체하세요
fun fetchAddress(lat: Double, lng: Double) {
viewModelScope.launch {
try {
val response = KakaoApiClient.apiService.getAddressFromCoords(
authorization = apiKey,
longitude = lng,
latitude = lat
)
val addressName = response.documents.firstOrNull()?.address?.address_name
_address.value = addressName ?: "주소 없음"
} catch (e: Exception) {
_address.value = "에러 발생: ${e.localizedMessage}"
}
}
}
}
---
✅ 5. Jetpack Compose에서 주소 출력
@Composable
fun AddressScreen(viewModel: LocationViewModel = viewModel()) {
val address by viewModel.address.collectAsState()
Column(modifier = Modifier.padding(16.dp)) {
Text(text = "현재 주소: ${address ?: "불러오는 중..."}")
Spacer(modifier = Modifier.height(8.dp))
Button(onClick = {
viewModel.fetchAddress(37.5665, 126.9780) // 서울시청 예시
}) {
Text("주소 가져오기")
}
}
}
---
🔚 마무리 정리
- ✔️ Retrofit + Coroutine을 통해 네트워크 처리를 안전하고 깔끔하게 구성
- ✔️ ViewModel과 StateFlow를 통해 UI와 데이터 연결
- ✔️ 권한과 REST API 키 보안을 고려해 실제 배포 환경에서는 백엔드 연동 또는 키 보호 필요
이제 Kakao Local API를 통해 GPS 좌표와 주소를 자유롭게 변환할 수 있습니다!
결과 이미지는 다음과 같이 설정이 가능 합니다.

📘 도움이 되었나요? 댓글이나 공유로 응원해 주세요 😊
반응형
'모바일 앱(안드로이드)' 카테고리의 다른 글
| Nearby Connections API에서 기기 이름이 다르게 나오는 이유 (2) | 2025.07.25 |
|---|---|
| Google Nearby Connections API 완전 정복 가이드 (feat Claude.ai) (6) | 2025.07.23 |
| Android에서 Hilt + Room + Firebase Realtime Database를 함께 사용하는 구조 설계 (4) | 2025.07.15 |
| 배드민터 리그 매니저 (가칭) 화면 구성 초안 (2) | 2025.07.09 |
| 배드민턴 리그 매니저(가칭) 앱 만들기 : 기능 설계 하기 (2) | 2025.07.07 |