Today's

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

모바일 앱(안드로이드)

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

Billcorea 2022. 6. 7. 23:16
반응형

앱을 만들다 보니, 주소 검색을 해야 하는 경우가 생긴다.  구글에서 찾아보면 추천해주는 방법이 2가지 정도로 압축 된다고 볼 수 있을 것 같다.
 
1. Daum 우편번호 서비스 
  장정 : API 가 필요하지 않다.  사용 제한도 없다.  
  단점 : 안드로이드 앱에서 직접 호출이 되지 않는다.
 
https://postcode.map.daum.net/guide#usage

Daum 우편번호 서비스

우편번호 검색과 도로명 주소 입력 기능을 너무 간단하게 적용할 수 있는 방법. Daum 우편번호 서비스를 이용해보세요. 어느 사이트에서나 무료로 제약없이 사용 가능하답니다.

postcode.map.daum.net

 
2. 주소 검색 서비스
    장점 : API 을 이용하여 사용한다.  java 코드를 활용할 수 있다.
    단점 : API 등록이 필요함.
https://business.juso.go.kr/addrlink/openApi/apiExprn.do?cPath=99MA

API 체험하기

business.juso.go.kr


사실은 잘 모르겠는데, 2번 방식으로 안드로이드에서 구현이 될까는 고민을 해 봐야 할 것 같다.  그래서 1번을 해 보기로 했는데, 
 
문제가 또 있다. java script 방식으로 처리를 해야 하기 때문에 실시간으로 활용할 수 있는 서버가 있어야 한다는 것이다. 검색을 통해서 얻은 결론은 호스팅 서비스를 사용하거나 하는 방법이 필요하다는 것인데,  저렴하게(?) 사용을 해 보려 하니, 방법이 좀 어렵다. 
 
그래서 blogger.com 에서 사용하는 블로그 페이지를 이용해서 만들어 보기로 했다.  먼저 blogger 페이지를 만들어 보았다.
이 페이지는 아래에서 기술하는 activity 에서 호출만 하면 주소 검색을 위한 팝업 페이지가 자동으로 열리게 된다.
https://billcoreatech.blogspot.com/2022/06/blog-post.html

안드로이드 앱 만들기 : 카카오(Daum) 주소 검색 API 호출 페이지 만들기.

이 페이지는 blogger 페이지를 이용해서 Kakao 우편번호 서비스를 활용하는 페이지 구현을 위한 페이지 입니다.  구성을 위해서 제일 먼저 blogger 의 수정을 시작 합니다. 수정할 때 HTML 보기를 선택

billcoreatech.blogspot.com

 
이제 구현을 해 보아야 겠다. 먼저 blogger 관리자 화면에서 새 페이지를 하나 만들고 html 편집 모드로 들어가 보겠다.
 

페이지 수정 html 모드 들어가기

그 다음은 html 편집기에서 아래와 같은 코드를 복사해 붙여 넣기를 하면 된다.  script 부분만 가져와 사용 하면 되기 떄문에 이 부분만 옮겨 넣으면 된다.

<div id="layer" style="-webkit-overflow-scrolling: touch; display: block; overflow: hidden; position: fixed; z-index: 1;"></div>

구성을 위해서 제일 먼저 blogger 의 수정을 시작 합니다.<script>

window.addEventListener("message", onReceivedPostMessage, false);

function onReceivedPostMessage(event){
    //..ex deconstruct event into action & params
    var action = event.data.action;
    var params = event.data.params;

    console.log("onReceivedPostMessage "+event);

}

function onReceivedActivityMessageViaJavascriptInterface(json){
     //..ex deconstruct data into action & params
     var data = JSON.parse(json);
     var action = data.action;
     var params = data.params;
       console.log("onReceivedActivityMessageViaJavascriptInterface "+event);
}


    // 우편번호 찾기 화면을 넣을 element
    var element_layer = document.getElementById('layer');

    function sample2_execDaumPostcode() {
        new daum.Postcode({
            oncomplete: function(data) {
			
                // 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

                // 각 주소의 노출 규칙에 따라 주소를 조합한다.
                // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
                var fullAddr = data.address; // 최종 주소 변수
                var extraAddr = ''; // 조합형 주소 변수

                // 기본 주소가 도로명 타입일때 조합한다.
                if(data.addressType === 'R'){
                    //법정동명이 있을 경우 추가한다.
                    if(data.bname !== ''){
                        extraAddr += data.bname;
                    }
                    // 건물명이 있을 경우 추가한다.
                    if(data.buildingName !== ''){
                        extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
                    }
                    // 조합형주소의 유무에 따라 양쪽에 괄호를 추가하여 최종 주소를 만든다.
                    fullAddr += (extraAddr !== '' ? ' ('+ extraAddr +')' : '');
                }
				
				
				var fullRoadAddr = data.roadAddress; // 도로명 주소 변수
                var extraRoadAddr = ''; // 도로명 조합형 주소 변수

                // 법정동명이 있을 경우 추가한다. (법정리는 제외)
                // 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
                if(data.bname !== '' && /[동|로|가]$/g.test(data.bname)){
                    extraRoadAddr += data.bname;
                }

                // 건물명이 있고, 공동주택일 경우 추가한다.
                if(data.buildingName !== '' && data.apartment === 'Y'){
                   extraRoadAddr += (extraRoadAddr !== '' ? ', ' + data.buildingName : data.buildingName);
                }

                // 도로명, 지번 조합형 주소가 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
                if(extraRoadAddr !== ''){
                    extraRoadAddr = ' (' + extraRoadAddr + ')';
                }
                // 도로명, 지번 주소의 유무에 따라 해당 조합형 주소를 추가한다.
                if(fullRoadAddr !== ''){
                    fullRoadAddr += extraRoadAddr;
                }				

				window.Android.processDATA(fullRoadAddr); // data.zonecode + ", " + 
            },
            width : '100%',
            height : '100%'
        }).embed(element_layer);

        // iframe을 넣은 element를 보이게 한다.
        element_layer.style.display = 'block';

        // iframe을 넣은 element의 위치를 화면의 가운데로 이동시킨다.
        initLayerPosition();
		
		
    }

    // 브라우저의 크기 변경에 따라 레이어를 가운데로 이동시키고자 하실때에는
    // resize이벤트나, orientationchange이벤트를 이용하여 값이 변경될때마다 아래 함수를 실행 시켜 주시거나,
    // 직접 element_layer의 top,left값을 수정해 주시면 됩니다.
    function initLayerPosition(){
        var width = (window.innerWidth || document.documentElement.clientWidth); //우편번호서비스가 들어갈 element의 width
        var height = (window.innerHeight || document.documentElement.clientHeight); //우편번호서비스가 들어갈 element의 height
        var borderWidth = 5; //샘플에서 사용하는 border의 두께

        // 위에서 선언한 값들을 실제 element에 넣는다.
        element_layer.style.width = width + 'px';
        element_layer.style.height = height + 'px';
        element_layer.style.border = borderWidth + 'px solid';
        // 실행되는 순간의 화면 너비와 높이 값을 가져와서 중앙에 뜰 수 있도록 위치를 계산한다.
        element_layer.style.left = (((window.innerWidth || document.documentElement.clientWidth) - width)/2 - borderWidth) + 'px';
        element_layer.style.top = (((window.innerHeight || document.documentElement.clientHeight) - height)/2 - borderWidth) + 'px';
    }

</script>
addr_daum.html
0.00MB

전체 코드는 위에 파일을 받아서 script 부분만 복사해서 붙여 넣으면 된다.  이제 안드로이드 앱에서 호출 하는 부분을 구현해 보아야 겠다.
 
먼저 internet 사용을 해야 하기 때문에 manifest 파일에 권한을 추가한다.

<uses-permission android:name="android.permission.INTERNET" />

 
다음은 호출하는 activity 을 구현해 보아야 겠다.  web page 을 호출해야 하기 때문에 layout 에 webview 을 넣고, 그 안에 위에서 작성한 페이지를 호출하면 된다.   이제 layout 을 구성해 보면 다음과 같다.
 

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

    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

 
아무것도 배치하지 않고 webView 만 배치 했다. 이번에는 activity 코드를 만들어 보아야 겠다.


import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.webkit.JavascriptInterface
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.appcompat.app.AppCompatActivity
import com.billcoreatech.multichat416.databinding.ActivityAddressApiBinding

class AddressApiActivity : AppCompatActivity() {
    private var webView: WebView? = null
    var TAG = "AddressApiActivity";
    lateinit var activityAddressApiBinding : ActivityAddressApiBinding

    inner class MyJavaScriptInterface {
        @JavascriptInterface
        fun processDATA(data: String?) {
            // 주소검색창에서 주소를 선택하면 그 결과값이 data 에 들어오기 떄문에 그것을 
            // 받아서 내가 만드는 앱 페이지로 넘기면 끝.
            val intent = Intent()
            intent.putExtra("data", data)
            setResult(RESULT_OK, intent)
            finish()
        }
    }

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

        // 위에서 작성한 블로거 페이지의 url 
        val blogspot = "https://billcoreatech.blogspot.com/2022/06/blog-post.html"

        activityAddressApiBinding = ActivityAddressApiBinding.inflate(layoutInflater)
        setContentView(activityAddressApiBinding.root)
        activityAddressApiBinding.webView!!.settings.javaScriptEnabled = true
        activityAddressApiBinding.webView!!.addJavascriptInterface(MyJavaScriptInterface(), "Android")
        activityAddressApiBinding.webView!!.webViewClient = object : WebViewClient() {
            override fun onPageFinished(view: WebView, url: String) {
               // 위 웹페이지가 load가 끝나면 코드에서 작성했던 script 을 호출한다. 
                view.loadUrl("javascript:sample2_execDaumPostcode();")
            }
        }
        // 위 블로거 페이지를 호출 한다.
        activityAddressApiBinding.webView!!.loadUrl(blogspot)
    }
}

이제 실행을 시켜 보아야 겠다.
 

012
주소검색 예시

 
이제 호출하는 구현은 되었으니,  나의 앱에 적용하는 것만 남았다.
 

반응형