(Android/안드로이드) WebViewClient로 URL / 커스텀 스킴 가로채서 처리하는 방법

✨ 개요

Android WebView를 사용하다 보면 다음과 같은 요구사항이 거의 반드시 등장한다.

이 모든 것을 담당하는 핵심 진입점이 바로 WebViewClient.shouldOverrideUrlLoading()이다.


1. 요약


2. WebViewClient의 역할

WebViewClient는 WebView 내부에서 발생하는 페이지 이동, URL 로딩, 에러 처리를 가로채는 역할을 한다.

webView.webViewClient = WebViewClient()


3. shouldOverrideUrlLoading() 기본 구조

Android API 21 이상에서는 아래 메서드를 사용해야 한다.

override fun shouldOverrideUrlLoading(
    view: WebView?,
    request: WebResourceRequest?
): Boolean

반환값 의미
true URL을 앱에서 직접 처리 (WebView는 로딩 안 함)
false WebView가 그대로 URL 로딩

4. 가장 기본 적인 URL 가로채기

webView.webViewClient = object : WebViewClient() {
    override fun shouldOverrideUrlLoading(
        view: WebView?,
        request: WebResourceRequest?
    ): Boolean {
        val url = request?.url.toString()

        return if (url.startsWith("http")) {
            false // WebView가 로딩
        } else {
            true  // 앱에서 처리
        }
    }
}

5. 커스텀 스킴(myapp://) 처리하기


6. intent:// 스킴 처리 (카카오, 결제, 인증 등)

웹에서 자주 사용하는 intent:// 스킴은 반드시 try-catch로 처리해야 한다.

override fun shouldOverrideUrlLoading(
    view: WebView?,
    request: WebResourceRequest?
): Boolean {
    val url = request?.url.toString()

    if (url.startsWith("intent://")) {
        try {
            val intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME)
            startActivity(intent)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return true
    }

    return false
}

7. 외부 앱 스킴 처리(tel:, mailto:, market:)

override fun shouldOverrideUrlLoading(
    view: WebView?,
    request: WebResourceRequest?
): Boolean {
    val uri = request?.url ?: return false

    return when (uri.scheme) {
        "tel", "mailto", "sms", "market" -> {
            startActivity(Intent(Intent.ACTION_VIEW, uri))
            true
        }
        else -> false
    }
}

8. 특정 도메인만 WebView에서 열기

private val allowedHost = "www.example.com"

override fun shouldOverrideUrlLoading(
    view: WebView?,
    request: WebResourceRequest?
): Boolean {
    val uri = request?.url ?: return false

    return if (uri.host == allowedHost) {
        false // WebView에서 로딩
    } else {
        startActivity(Intent(Intent.ACTION_VIEW, uri))
        true
    }
}


Related Posts