밤에 아시는 분이 갑자기 도움을 요청 하셨습니다. 다음 주소 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
'2023년 이전 > Android' 카테고리의 다른 글
코틀린 안드로이드 익스텐션 비추천 (1) | 2020.11.06 |
---|---|
Android - 라이브러리를 활용한 인디케이터 ( dotsIndicator ) (0) | 2020.11.06 |
Ime hide catch (0) | 2020.09.25 |
MpAndroidChart 사용 후기 (1) | 2020.05.30 |
java.lang.IllegalArgumentException: pointerIndex out of range (0) | 2020.05.30 |