Today's

길을 나서지 않으면 그 길에서 만날 수 있는 사람을 만날 수 없다

모바일 앱(안드로이드)

안드로이드 앱 만들기 : 주소 API 사용해 Kakao 우편번호 서비스 활용해 보기 #2 (feat jetpack compose)

Billcorea 2023. 2. 14. 22:22
반응형

이전 이야기 

https://billcorea.tistory.com/215

 

안드로이드 앱 만들기 : 주소 API 사용해 Kakao 우편번호 서비스 활용해 보기

앱을 만들다 보니, 주소 검색을 해야 하는 경우가 생긴다. 구글에서 찾아보면 추천해주는 방법이 2가지 정도로 압축 된다고 볼 수 있을 것 같다. 1. Daum 우편번호 서비스 장정 : API 가 필요하지 않

billcorea.tistory.com

오늘은 이전 포스팅의 내용에서 일부 변형된 모습에 대한 이야기를 잠시해 보겠습니다. 

이전 포스팅에서는 webView을 layout.xml을 이용해서 구현한 모습에 대한 이야기를 했습니다. 

 

오늘 구현한 소스는 jetpack compose 을 이용해서 구현한 코드입니다. 

 

먼저 gradle 파일에 webview 사용을 위해서 선언을 해야 합니다. android API 33을 target으로 하고 있어서 아래 버전으로 설정을 해 주면 가능합니다.

// Webview
implementation "com.google.accompanist:accompanist-webview:0.24.13-rc"

 

webview을 호출하는 activity는 다음과 같이 전체 코드를 작성했습니다. 주의해서 봐야 할 부분은 다음과 같습니다.

  • MyJavaScriptInterface 함수 : 카카오 API 페이지에서 선택한 주소 정보를 받아서 전달하는 역할
  • BackHandler : 카카오 API 페이지에서 뒤로 가기를 선택했을 때 처리 하는 역할
  • webviewClient의 onPageFinished : 카카오 API 페이지 로딩이 완료되면 주소검색 함수를 호출하는 역할

이런 정도의 역할들에 문제가 없도록 구현하는 것이 체크가 되어야 할 부분으로 생각이 됩니다.

import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.webkit.JavascriptInterface
import android.webkit.WebView
import androidx.activity.ComponentActivity
import androidx.activity.compose.BackHandler
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import com.billcoreatech.remotepayment0119.ui.theme.RemotePayment0119Theme
import com.google.accompanist.web.*

class AddressFindActivity : ComponentActivity() {


    inner class MyJavaScriptInterface {

        @JavascriptInterface
        fun processDATA(data: String?) {
            Log.e("TAG", "error ...........................${data}")

            val intent = Intent()
            intent.putExtra("data", data)
            setResult(AppCompatActivity.RESULT_OK, intent)
            finish()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            RemotePayment0119Theme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    WebViewForAddress(this@AddressFindActivity,
                        doFinish = {
                            val intent = Intent()
                            setResult(AppCompatActivity.RESULT_CANCELED, intent)
                            finish()
                        }
                    )
                }
            }
        }
    }
}

@SuppressLint("JavascriptInterface")
@Composable
fun WebViewForAddress(addressFindActivity: AddressFindActivity, doFinish:() -> Unit) {

    val blogspot = "https://billcoreatech.blogspot.com/2022/06/blog-post.html"

    val webViewState =
        rememberWebViewState(
            url = blogspot,
            additionalHttpHeaders = emptyMap()
        )
    val webChromeClient = AccompanistWebChromeClient()
    val webViewNavigator = rememberWebViewNavigator()

    WebView(
        state = webViewState,
        client = object : AccompanistWebViewClient() {
            override fun onPageFinished(view: WebView?, url: String?) {
                view?.loadUrl("javascript:sample2_execDaumPostcode();")
            }
        },
        chromeClient = webChromeClient,
        navigator = webViewNavigator,
        onCreated = { webView ->
            with(webView) {
                settings.run {
                    javaScriptEnabled = true
                    domStorageEnabled = true
                    javaScriptCanOpenWindowsAutomatically = true
                }
                addJavascriptInterface(addressFindActivity.MyJavaScriptInterface(), "Android")
            }
        }
    )

    BackHandler(enabled = true) {
        if (webViewNavigator.canGoBack) {
            webViewNavigator.navigateBack()
        } else {
            doFinish()
        }
    }
}

코드 중에 있는 blogspot의 URL 은 제가 만들어둔 blog의 URL 페이지입니다. 서버가 없기 때문에 blog 을 이용해서 사용하는 페이지 입니다.  실제 처리는 카카오 API에서 하는 것이기 때문에 특별한 문제는 없을 듯합니다. 

 

실행되는 이미지

 

이렇게 해서 실행해 보면 카카오 API에서 선택한 주소 정보를 받아와서 작업 중인 입력창에 값이 채워지는 것을 확인할 수 있었습니다. 

 

주소 검색창을 작성하시는 데 도움이 되기 바랍니다.

 

반응형