본문 바로가기

안드로이드

webView에서 window.open(), window.close() 처리

webView에서 window.open(), window.close() 처리

방법: webChromeClient를 사용하여 해결합니다. dialog를 사용하는 방식이 있으나 mWebViewPop에 새 창의 정보를 담아 FrameLayout에 추가하는 방식을 사용하였습니다.

 

<MainActivity.kt>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package com.example.webview_windowopen
 
import android.os.Build
import android.os.Bundle
import android.os.Message
import android.util.Log
import android.webkit.WebChromeClient
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.FrameLayout
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
 
 
class MainActivity : AppCompatActivity() {
    lateinit var mContainer : FrameLayout
    lateinit var mWebViewPop : WebView
    lateinit var myWebView : WebView
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.webview)
        WebView.setWebContentsDebuggingEnabled(true)
        mContainer = findViewById(R.id.webview_frame)
        mWebViewPop = findViewById(R.id.webview)
        myWebView = findViewById(R.id.webview)
        myWebView.loadUrl("file:///android_asset/webViewTest.html")
        myWebView.apply {
            webViewClient = WebViewClient()
            settings.javaScriptEnabled = true
            settings.javaScriptCanOpenWindowsAutomatically = true
            settings.setSupportMultipleWindows(true)
        }
 
        myWebView.webChromeClient = object : WebChromeClient(){
            override fun onCreateWindow(view: WebView?, isDialog: Boolean, isUserGesture: Boolean, resultMsg: Message?): Boolean {
                Toast.makeText(this@MainActivity, "onCreateWindow", Toast.LENGTH_SHORT).show()
                mWebViewPop = WebView(this@MainActivity).apply {
                    webViewClient = WebViewClient()
                    settings.javaScriptEnabled = true
                }
                mContainer.addView(mWebViewPop)
 
                mWebViewPop.webChromeClient = object : WebChromeClient() {
                    override fun onCloseWindow(window: WebView?) {
                        mContainer!!.removeView(window)
                        window!!.destroy()
                    }
                }
                (resultMsg?.obj as WebView.WebViewTransport).webView = mWebViewPop
                resultMsg.sendToTarget()
                return true
            }
        }
    }
 
    @RequiresApi(Build.VERSION_CODES.O)
    override fun onBackPressed() {
        //웹사이트에서 뒤로 갈 페이지 존재시
        if(mWebViewPop.canGoBack() && mContainer.childCount>=2) {
            Toast.makeText(this"back", Toast.LENGTH_SHORT).show()
            mWebViewPop.goBack() // 웹사이트 뒤로가기
        }
        else if(!mWebViewPop.canGoBack() && mContainer.childCount>=2 ){
            Toast.makeText(this"onCloseWindow", Toast.LENGTH_SHORT).show()
            mWebViewPop.webChromeClient?.onCloseWindow(mWebViewPop) //onCloseWindow
        }
        else{
            Toast.makeText(this"webview close", Toast.LENGTH_SHORT).show()
            super.onBackPressed() //webview 종료
        }
    }
}
cs

 

<webview.xml>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">
 
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/webview_frame">
        <WebView
            android:id="@+id/webview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />
    </FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
cs

 

<webViewTest.html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script>
            function popup(){
                let options = "toolbar=no,scrollbars=no,resizable=yes,status=no,menubar=no,width=1200, height=800, top=0,left=0";
                 window.open("http://www.naver.com","_blank", options);
            }
        </script>
    </head>
    <body>
        <button onclick=popup()>naver popup</button>
    </body>
</html>
cs

 

<chrome://inspect 를 이용한 디버깅>

 

<시연영상>

 

추가할 부분: 앱은 새 창을 표시하는 방법에 주의해야 합니다. 기존 웹 보기 위에 단순히 창을 겹쳐서 표시하면 사용자가 보고 있는 사이트를 잘못 알 수 있습니다. 따라서 URL창을 구현하는 것이 맞습니다. [1]

 

전체 코드:

https://gitlab.com/kingdom3/webview_window.open

 

참조:

[1] 공식문서

https://developer.android.com/reference/android/webkit/WebChromeClient

 

[2] 자바-dialog 방식으로 window.open 처리

https://helloit.tistory.com/303

 

[3] 코틀린-FrameLayout 방식으로 window.open 처리

https://onedaycodeing.tistory.com/152 (코틀린-FrameLayout 방식으로 window.open 처리)

 

[4] 코틀린- dialog 방식으로 window.open 처리

https://superwony.tistory.com/150

 

[5]

https://kimdabang.tistory.com/entry/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-WebViewClient%EC%99%80-WebChromeClient