딥링크로 앱 실행 및 특정 페이지로 이동하기

    딥링크로 앱 실행 및 특정 페이지로 이동하기


    기사 요약

    Android Shoplive Player SDK는 상품 클릭, 공지사항 클릭 등의 다양한 이벤트를 통해서 Shoplive Player가 PIP로 전환될 때, ActivityManagergetAppTasks()를 사용하여 고객사 앱의 Task를 찾고 moveToFront() 함수로 고객사 앱을 foreground로 올립니다.

    • 앱 아이콘을 터치하여 앱을 열어 Shoplive Player를 실행하면 PIP로 내려가는 시점에 Launcher Task를 찾아 고객사 앱을 foreground로 올리면서 전환이 됩니다.

    • 그런데 딥링크로 앱을 열면 PIP로 내려갈 때, 경우에 따라서는 고객사 앱의 Task를 찾지 못하여 foreground로 올리지 못하게 됩니다. 이는 딥링크를 실행하는 주체가 Intent.FLAG_ACTIVITY_NEW_TASK flag를 적용하여 호출했는지 여부에 따라 다릅니다.


    안드로이드 딥링크 문서에는 아래와 같이 설명되어 있습니다.

    암시적 딥 링크를 트리거할 때 백 스택의 상태는 암시적 Intent가 Intent.FLAG_ACTIVITY_NEW_TASK 플래그와 함께 실행되었는지에 따라 다릅니다.

    • 플래그가 설정되면 작업 백 스택이 삭제되고 딥 링크 대상으로 대체됩니다. 명시적 딥 링크와 마찬가지로 그래프를 중첩할 때 각 중첩 수준의 시작 대상, 즉 계층 구조에 있는 각 요소의 시작 대상도 스택에 추가됩니다. 즉, 사용자가 딥 링크 대상에서 뒤로 버튼을 누르면 마치 진입점에서 앱에 들어간 것처럼 탐색 스택을 다시 위로 탐색합니다.

    • 플래그가 설정되지 않으면 암시적 딥 링크가 트리거된 이전 앱의 작업 스택에 남게 됩니다. 이 경우 뒤로 버튼을 누르면 다시 이전 앱으로 돌아가는 반면 위로 버튼을 누르면 탐색 그래프 내 계층 구조의 상위 대상에서 앱 작업이 시작됩니다.


    따라서 딥링크 실행 주체의 Intent.FLAG_ACTIVITY_NEW_TASK flag 적용 여부와 상관없이 Shoplive Player의 동일한 동작을 원한다면 딥링크 처리를 담당하는 SchemeActivity를 별도로 구현하고 다음 Activity를 호출할 때 Intent.FLAG_ACTIVITY_NEW_TASK flag를 사용해야 합니다.


    Sample code

    shoplive://live?ak={accessKey}&ck={campaignKey}

    AndroidManifest.xml

    <activity
    	android:name=".SchemeActivity"
    	android:exported="true"
    	android:noHistory="true"
    	android:screenOrientation="portrait">
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
    
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
    
        <data
          android:host="live"
          android:scheme="shoplive" />
      </intent-filter>
    </activity>

    SchemeActivity

    class SchemeActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            execute(intent)
        }
    
        override fun onNewIntent(intent: Intent?) {
            super.onNewIntent(intent)
    
            execute(intent)
        }
    
        private fun execute(intent: Intent?) {
            intent ?: return
    
            val data = intent.data
            val accessKey = data?.getQueryParameter("ak") ?: return
            val campaignKey = data.getQueryParameter("ck")
    
            if (accessKey.isNotEmpty() && !campaignKey.isNullOrEmpty()) {
                // Intent.FLAG_ACTIVITY_NEW_TASK 적용하여 MainActivity 호출
                val intent = Intent(this, MainActivity::class.java)
                intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
                intent.putExtra("accessKey", accessKey)
                intent.putExtra("campaignKey", campaignKey)
                startActivity(intent)
            }
        }
    }

    MainActivity

    class MainActivity : AppCompatActivity() {
    
        companion object {
            private const val ACCESS_KEY = "accessKey"
            private const val CAMPAIGN_KEY = "campaignKey"
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            val accessKey = intent.getStringExtra(ACCESS_KEY)
            val campaignKey = intent.getStringExtra(CAMPAIGN_KEY)
            if (accessKey?.isNotEmpty() == true && campaignKey?.isNotEmpty() == true) {
                // Shoplive Player 실행 또는 라이브 페이지 이동하기 구현
            }
        }
    }