Android

[Android] WebView Url 여러개 띄우기(feat.Java)

김한토 2025. 2. 25. 09:42
반응형

 한 웹뷰에 여러 url을 띄우는 작업을 하게 되었는데 onPagedFinish에 다음 url로드를 달아 놓고 닫기 버튼을 누르니

scripts may close only the windows that were opened by them. 라는 로그가 뜨며 window.close()가 작동하지 않았다. 

 

이는 사용자가 명시적으로 연 창이 아니라면 window.close() 실행을 허용하지 않기 때문이다.  

 

이를 해결하기 위해 xml에 webView를 넣는 것이 아닌 framLayout을 선언하고 url이 여러개 있을때 한개의 url이 닫히면 새로운 webView를 생성하게 했다. 

 

@SuppressLint("SetJavaScriptEnabled")
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Log.d(TAG, "onViewCreated()");

        // JavaScript 설정
        WebView webView = new WebView(requireContext());
        webView.setWebViewClient(new WebViewClient());
        webView.setWebChromeClient(new CustomWebChromeClient());

        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
        webView.getSettings().setSupportMultipleWindows(true);

        // WebView를 컨테이너에 추가
        webViewContainer.addView(webView);
        currentWebView = webView;
        
        loadNextUrl();
    }

 

// 다음 URL 로드
    private void loadNextUrl() {
        if (currentUrlIndex < noticeList.size()) {
            String url = noticeList.get(currentUrlIndex);
            currentWebView.loadUrl(url);
            Log.d(TAG, "Loading URL: " + url);
        } else {
            dismiss();
        }
    }


    // CustomWebChromeClient 클래스
    private class CustomWebChromeClient extends WebChromeClient {
        @SuppressLint("SetJavaScriptEnabled")
        @Override
        public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {

            // 새 창을 위한 WebView 생성
            WebView newWebView = new WebView(requireContext());
            newWebView.setWebViewClient(new WebViewClient());
            newWebView.setWebChromeClient(this);

            // WebView 설정
            newWebView.getSettings().setJavaScriptEnabled(true);
            newWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
            newWebView.getSettings().setSupportMultipleWindows(true);

            // WebView를 컨테이너에 추가
            webViewContainer.addView(newWebView);

            // 새 창을 열기 위한 WebView 설정
            WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
            transport.setWebView(newWebView);
            resultMsg.sendToTarget();

            return true;
        }

        @SuppressLint("SetJavaScriptEnabled")
        @Override
        public void onCloseWindow(WebView window) {
            super.onCloseWindow(window);

            if (window != null && window.getParent() instanceof ViewGroup) {
                ((ViewGroup) window.getParent()).removeView(window);
            }

            // 다음 URL 로드
            currentUrlIndex++;
            if (currentUrlIndex < noticeList.size()) {
                // 새 창 생성 및 URL 로드
                WebView newWebView = new WebView(requireContext());
                newWebView.setWebViewClient(new WebViewClient());
                newWebView.setWebChromeClient(this);

                newWebView.getSettings().setJavaScriptEnabled(true);
                newWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
                newWebView.getSettings().setSupportMultipleWindows(true);

                webViewContainer.addView(newWebView);
                currentWebView = newWebView;

                loadNextUrl();
            } else {
                // 모든 URL을 로드한 후 DialogFragment를 닫음
                dismiss();
            }
        }
    }
반응형