개발

Flutter에서 갤럭시 폴드 5(안드로이드) 카카오톡 열기 이슈 및 해결 (window.open & intent)

Padd60 2024. 1. 24. 22:43

어떤 이슈?

회사에서 하이브리드 앱 개발 중 웹뷰단에서 카카오톡 문의하기를 눌렀을때 안드로이드 기기에서만 카카오톡이 안 열리는 문제가 있었다.

 

이슈 유형 정리

기본 메인 이슈는 카카오톡 문의하기 클릭 시 카카오톡이 안 열리는 문제

  • 아이폰
    • 너무나도 잘 열림
    • 카카오톡 없으면 다운로드하라는 브라우저 창도 띄워짐
    • 있으면 해당 카톡 열어서 1대1 채팅까지도 가능
  • 갤럭시 S 시리즈
    • 카카오톡이 있을때는 잘 열림
    • 미설치시에는 아무현상도 일어나지 않거나 살짝의 코드 수정시 intent 주소와 함께 UNKOWN_SCHEMA 이슈가 나옴
  • 갤럭시 폴드 시리즈
    • 접었을때는 S 시리즈와 동일한 현상임
    • 펼쳤을때는 아예 아무 현상도 벌어지지 않음

 

위와 같은 기종 별 현상이 차이가 나서 왜 그런지 정말 고민과 고생이 많았지만 해결을 했다.

위 갤럭시에서 발생한 문제는 갤럭시 폴드 5에서 일어난 현상 원인과 해결방법으로 설명이 다 가능하다.

 

해결방법

먼저 갤럭시 폴드 5는 펼쳤을때는 User agent를 웹으로 인식하고 접었을때는 모바일로 인식해서 

각 펼치고 접었을때 나타나는 현상이 달랐던 것이다.

 

펼쳤을때 해결 방법

기본적으로 flutter 웹뷰 내에서는 window.open으로 새 창을 열지 못한다.

때문에 사용하고 있는 inappwebview 패키지에서 onCreateWindow 이벤트에

해당 동작을 인식하고 받아 새로운 웹뷰를 띄워서 해결해야 했다.

 

main.dart 내 inappwebview 생성 함수 내에 아래 코드를 추가하여 해결했다.

            onCreateWindow: (controller, createWindowRequest) async {
              showDialog(
                  context: context,
                  builder: (context){
                    return InAppWebView(
                              windowId: createWindowRequest.windowId,
                              shouldOverrideUrlLoading: _shouldOverrideUrlLoading,
                              initialOptions: InAppWebViewGroupOptions(
                                android: AndroidInAppWebViewOptions(
                                    builtInZoomControls: true,
                                    thirdPartyCookiesEnabled: true,
                                ),
                                crossPlatform: InAppWebViewOptions(
                                  cacheEnabled: true,
                                  javaScriptEnabled: true,
                                  useShouldOverrideUrlLoading: true,
                                  userAgent: "Mozilla/5.0 (Linux; Android 9; LG-H870 Build/PKQ1.190522.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari/537.36"
                                ),
                              ),
                              onWebViewCreated: (InAppWebViewController controller) {

                              },
                              onLoadStart: (InAppWebViewController controller, url) async {
                                print("onLoadStart popup $url");
                              },
                              onLoadStop: (InAppWebViewController controller, url) async {
                                print("onLoadStop popup $url");
                              },
                              onCloseWindow: (controller) {
                                if (Navigator.canPop(context)) {
                                  Navigator.pop(context);
                                }
                              },
                            );
                  }              
              );

              return true;
            },

 

https://gist.github.com/pichillilorenzo/059b021067a32a71b0c399b561135b6a

 

InAppWebView - Popup Window Example

InAppWebView - Popup Window Example. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

위 링크를 보고 참고해서 해결했다.

 

실제로 동작을 시켜보니

새로운 창이 뜨면서 

카카오톡이 미설치된 상태에서는 카카오톡 최신버전을 설치할거냐는 화면이 뜨고

카카오톡이 설치된 상태에서는 해당 카카오톡 앱이 켜지면서 문의로 잘 이어지는 것을 볼 수 있었다.

 

접었을때 해결방법

접었을때 해결방법으로 갤럭시 S 시리즈에서 동작하지 않는 현상도 해결할 수 있다.

 

https://developers.kakao.com/docs/latest/ko/javascript/hybrid#android-execute-kakaotalk

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

 

위처럼 카카오에서 하이브리드 앱을 위한 가이드를 확인해볼 수 있다.

 

헌데 기존 코드에서 해당 intent 관련 처리를 해줬음에도 해결이 되지 않는 것이다.

 

그래서 팀원분들과 논의하고 카카오에 문의도 한 결과

 

                // Intent 생성
                val intent = Intent.parseUri(request.url.toString(), Intent.URI_INTENT_SCHEME)

                // 실행 가능한 앱이 있으면 앱 실행
                if (intent.resolveActivity(packageManager) != null) {
                    startActivity(intent)
                    Log.d(TAG, "ACTIVITY: ${intent.`package`}")
                    return true
                }

                // Fallback URL이 있으면 현재 웹뷰에 로딩
                val fallbackUrl = intent.getStringExtra("browser_fallback_url")
                if (fallbackUrl != null) {
                    view.loadUrl(fallbackUrl)
                    Log.d(TAG, "FALLBACK: $fallbackUrl")
                    return true
                }

 

위 코드에서 intent는 잘 로그가 찍히고

 

카카오톡 설치가 되어있으면 intent.resolveActivity(packageManager)가 null이 아니라 카카오톡이 잘 열리지만

 

카카오톡을 미설치한 상태라면 intent.resolveActivity(packageManager)가 null이고

이후 동작하는 fallbackUrl 마저 null이라서 아무런 동작을 하지 않는것이었다.

 

원인은 명쾌했는데

기존에는 browser_fallback_url을 intent 정보에 넣어줬지만

최근에 카카오 측에서 보안상의 이유로 해당 url을 제거해서 실제 가이드된 내용과 다르게 동작했던것이다.

 

따라서 intent.resolveActivity(packageManager)가 null이고 kakao 또는 plusfriend와 같은 카카오 관련 문구가 있을때는

startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.kakao.talk"))

 

 

위와 같이 카카오톡 마켓으로 넘기는 동작을 수행하니 비로소 원하는대로 카카오톡 설치로 넘어가고 

설치 후에도 카카오톡 문의하기에서 1대1 채팅으로 이어지는 것을 확인할 수 있었다.

 

장장 이걸 해결하기 위해 많은 시간을 허비했지만....

그래도 해결하고 나니 보람은 있었다고 생각한다.

 

그리고 더더욱 느껴지는건...

앱개발은 너무나도 어렵고 인내심이 많이 필요한 일이라는것을 깨달은 경험이었다.

 

그나마 하이브리드라서 웹을 중심으로 개발한다는것에 위안을 삼는다 ㅎㅎ

앱에 대한 이해와 지식이 쌓이기 전에는 앞으로 네이티브와 연계되야하는 기능을 최대한 적게 가져가는 방향으로 개발을 진행할 예정이다.