본문 바로가기
2023년 이전/Android

[API] 다음 주소 API 활용하기

by JeongUPark 2020. 10. 7.
반응형

밤에 아시는 분이 갑자기 도움을 요청 하셨습니다. 다음 주소 API를 쓰는데 웹뷰에서 계속 흰색 화면만 나타난다고 말 씀 해 주셨습니다.

 

그래서 이번은 다음 주소 API 활용하면서 격은 시행 착오 및 해결을 작성해보겠습니다.

관련 코드는 github.com/jeongupark9/DaumapiwebCallFromAndroidWebview 에 올려두었습니다.

1. 웹에서 팝업 형태로 화면을 띄우고 있었다.

우선 그 분이 전달 해준 url로 접속을 해보았습니다.

그랬더니 위와 같이 팝업 형태로 주소 입력 창을 띄워주고 있었습니다.

그래서 WebView에서 다이얼로그 형태를 사용하여 띄어주기 위한 작업을 수행하였습니다.

결과 화면

 

위 결과에 대한 code는 다음과 같습니다.

Xml

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <WebView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/webview"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

그리고 인터넷 사용을 위해 manifest에 인터넷 Permission을 추가 합니다.

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

그리고 Activity는 다음과 같이 작성 합니다.

class MainActivity : AppCompatActivity() {

    private var webView: WebView? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        webView = webview
        webView!!.apply {
            settings.javaScriptEnabled = true
            settings.javaScriptCanOpenWindowsAutomatically = true
            settings.setSupportMultipleWindows(true)
            webViewClient = client
            webChromeClient = object : WebChromeClient() {
                // Grant permissions for cam
                override fun onCreateWindow(view: WebView, isDialog: Boolean, isUserGesture: Boolean, resultMsg: Message): Boolean {
                    val newWebView = WebView(this@MainActivity)
                    newWebView.settings.javaScriptEnabled = true
                    val dialog = Dialog(this@MainActivity).apply {
                        setContentView(newWebView)
                    }
                    dialog.show()
                    val lp = WindowManager.LayoutParams().apply {
                        copyFrom(dialog.window!!.attributes)
                        width = WindowManager.LayoutParams.MATCH_PARENT
                        height = WindowManager.LayoutParams.MATCH_PARENT
                    }
                    dialog.window!!.attributes = lp
                    newWebView.webChromeClient = object : WebChromeClient() {
                        override fun onCloseWindow(window: WebView) {
                            dialog.dismiss()
                        }
                    }
                    (resultMsg.obj as WebViewTransport).webView = newWebView
                    resultMsg.sendToTarget()
                    return true
                }
            }
        }
        webView!!.loadUrl("api를 사용하는 웹 주소")
    }

    var client: WebViewClient = object : WebViewClient() {

        @TargetApi(Build.VERSION_CODES.N)
        override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
            return false
        }

    }

}

 

2. 그런데 이게 정말 최선일까?

그런데 저렇게 다이얼로그로 띄우는게 최선이 었을까? 싶어서 계속 검색을 해보았습니다.

 

우선 다음 우편번호 서비스에서는 다음 code를 추가 한 페이지를 호출하면 된다고 하고, 

<script src="https://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
    new daum.Postcode({
        oncomplete: function(data) {
            // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분입니다.
            // 예제를 참고하여 다양한 활용법을 확인해 보세요.
        }
    }).open();
</script>

많은 사람들이 

<?php
header("Content-Type: text/html; charset=UTF-8");
?>
<script src="https://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
    new daum.Postcode({
        oncomplete: function(data) {
            // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분입니다.
            // 예제를 참고하여 다양한 활용법을 확인해 보세요.
        }
    }).open();
</script>

이렇게 php를 사용하여 서버에 페이지를 올리고 호출하면 팝업으로 안뜨고 정상적으로 웹뷰에 나타난다고 해서 저도 한번 해봤습니다.

android Code 

class MainActivity : AppCompatActivity() {

    private var webView: WebView? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        webView = webview
        webView!!.apply {
            settings.javaScriptEnabled = true
            settings.javaScriptCanOpenWindowsAutomatically = true
            webViewClient = client
            webChromeClient = WebChromeClient()

        }
        webView!!.loadUrl("api 호출하는 웹 주소")
    }

    var client: WebViewClient = object : WebViewClient() {

        @TargetApi(Build.VERSION_CODES.N)
        override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
            return false
        }

    }

}

이렇게 테스트를 해보니 

이런 결과를 확인 할 수 있었습니다.

 

3. 그런데 php만이 방법일까?

그냥 html로는 할 수 없을까 하여 구글링도 해보고 이것저것 해본 결과 다음과 같이 작업하여 비슷하게 화면을 볼 수 있었습니다.

 

html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Welcome to Firebase Hosting</title>


  </head>
  <body>
    <script src="https://ssl.daumcdn.net/dmaps/map_js_init/postcode.v2.js?autoload=false"></script>
  <!-- !!중요. - autoload=false 를 반드시 붙혀주셔야 합니다.-->
  <script>
      //load함수를 이용하여 core스크립트의 로딩이 완료된 후, 우편번호 서비스를 실행합니다.
    var element_layer = document.getElementById('layer');
      daum.postcode.load(function(){
          new daum.Postcode({
              oncomplete: function(data) {
                  // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분입니다.
                  // 예제를 참고하여 다양한 활용법을 확인해 보세요.
              }
          }).embed();
      });
  </script>
  </iframe>
  </body>
</html>

activity

class MainActivity : AppCompatActivity() {

    private var webView: WebView? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        webView = webview
        WebView.setWebContentsDebuggingEnabled(true)
        webView!!.apply {
            settings.javaScriptEnabled = true
            settings.javaScriptCanOpenWindowsAutomatically = true
            settings.setSupportMultipleWindows(true)
            webViewClient = client

        }
        webView!!.loadUrl("api 주소")
    }

    var client: WebViewClient = object : WebViewClient() {

        @TargetApi(Build.VERSION_CODES.N)
        override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
            return false
        }

    }

}

결과

이 경우에는 화면이 자동으로 조절 되지 않는 현상이 있는데, 이는 javascriptinterface나 css를 통하여 충분히 해결 할 수 있을 것 같습니다.

 

 

기타 사항

1. 호스팅은 파이어베이스 호스팅을 사용 했습니다.

2. activity 코드를 보면 중간에 WebView.setWebContentsDebuggingEnabled(true) 있는데 이것을 적용하면 

크롬 창에 chrome://inspect 라고 치면 아래와 같은 화면이 나오고 

inspect를 선택하면

아래와 같은 웹 개발자 도구를 볼 수 있습니다. (관련 내용은 여기서developers.google.com/web/tools/chrome-devtools/remote-debugging/webviews?hl=ko 서 확인)

3. 한번 호출하면 WebView cache에 html 파일이 남아서 동일 주소에서는 변경된 내용이 반영된 html을 가져오지 않고 cache 된 html을 사용하는 것으로 보입니다. (inspector로 확인). 리빌드 할때마다 변경 사항을 적용해주려면 매번 cache를 clear 해주거나 앱을 지우고 다시 설치하면 될 것 같습니다.

 

4. 관련 git code 주소 : github.com/jeongupark9/DaumapiwebCallFromAndroidWebview

반응형