본문 바로가기

안드로이드/팁

[Android] Webview내 카카오톡 공유하기 에러 / 해결방안

반응형

앱내 웹뷰에서 카카오톡으로 공유하는 기능이 포함되어 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
}

 

또 다른 문제 : 'market://details?id=' 비정상 작동

url에 마켓으로 이동시키기 위한 정보가 담겨있지 않아 하드코딩 방식으로 카카오 링크가 포함되어 있는 경우 카카오톡을 설치하도록 유도 했습니다. 해당 내용은 카카오 데브에 남아 있지 않더라구요. 구현하시는 분들은 참고하시면 될것 같습니다.

 

 

 

 

 

반응형

'안드로이드 > ' 카테고리의 다른 글

안드로이드 launch mode 선택  (0) 2020.11.13
TargetSdkApi 29 대응하기  (0) 2020.10.30
Firebase Crashlytics Sdk 업데이트  (3) 2020.09.24
카카오 애드핏 적용 후기  (0) 2020.08.05
게시판 구현 복기  (0) 2020.07.16