본문 바로가기

study

[Android] Webview내 카카오톡 공유하기 에러 / 해결방안출처: https://superwony.tistory.com/115 [개발자 키우기]

앱내 웹뷰에서 카카오톡으로 공유하는 기능이 포함되어 WebviewClient()에  intent 기능을 수행하도록 처리 했습니다. 웹뷰에서 다른 앱을 실행시킬때 intent://로 시작해 보통 아래 코드와 같이 적용하면 문제 없이 작동했었습니다.

class BaseWebClient(val context: Context) : WebViewClient() {

    var isHistoryClear = false

    override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
        if(url != null){
            when{
                url.startsWith("intent://") -> {
                    try {
                        val intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME)
                        context.startActivity(intent)
                        return true
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                }
                url.startsWith("market://") -> {
                    try {
                        val intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME)
                        if (intent != null) {
                            context.startActivity(intent)
                        }
                        return true
                    } catch (e: URISyntaxException) {
                        e.printStackTrace()
                    }
                }
            }

        }
        view?.loadUrl(url)
        return false
    }
}

근데 이번에 테스트 해본 결과 카카오톡 공유하기 버튼을 눌렀을때 'intent:' 로 들어와 위의 코드가 정상적으로 작동하지 않고 웹뷰에 에러 페이지가 노출 됐습니다. ( 웹 주소가 아닌데 loadUrl 메소드를 탓기 때문 ) 

 

해결 방법

검색 해본 결과 같은 에러 현상을 겪는 사람들이 꽤 있었고 그에 카카오 데브에서 남긴 답변을 보고 해결할 수 있었습니다. ( 링크 )

요약해보면 4.4 sdk 부터 웹뷰가 Chromium기반으로 변경되면서 intent를 지원하지 않아서 발생하는 문제로 이전과 다르게 intent를 핸들링 해야합니다. 

val PROTOCOL_START = "intent:"
val PROTOCOL_END = ";end;"
val PROTOCOL_INTENT = "#Intent;"
val GOOGLE_PLAY_STORE_PREFIX = "market://details?id=";

var url = uri.toString()
if (url.startsWith(PROTOCOL_START)) {
	var customUrlStartIndex = PROTOCOL_START.length
    var customUrlEndIndex = url.indexOf(PROTOCOL_INTENT)
    if(customUrlEndIndex< 0 ){
    	return false
    }else{
    	try {
        	var resultUrl = url.substring(customUrlStartIndex, customUrlEndIndex)
            val intent = Intent.parseUri(resultUrl, Intent.URI_INTENT_SCHEME)
            context.startActivity(intent)
            return true
        } catch (e: ActivityNotFoundException) {
			// 카카오 링크가 포함된 경우
			if(url.contains("kakaolink://send")){
            	context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(GOOGLE_PLAY_STORE_PREFIX + "com.kakao.talk")))
                return true
            }
            var packageStartIndex = customUrlEndIndex + PROTOCOL_INTENT.length
            var packageEndIndex = url.indexOf(PROTOCOL_END)

            var packageName = url.substring(packageStartIndex,if(packageEndIndex< 0) url.length else packageEndIndex)
            context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(GOOGLE_PLAY_STORE_PREFIX + packageName)))
        }
        return true
	}
}else{
	return false
}



출처: https://superwony.tistory.com/115 [개발자 키우기]