SDK ์ฝ์
๋ถ์ ์์คํ ์ ํต์ฌ ๊ตฌ์ฑ์์์ธ SDK๋ ์ฑ ์ธ์คํจ๊ณผ ์ธ์ฑ ์ด๋ฒคํธ๋ฅผ ์ดํธ๋ฆฌ๋ทฐํธํ๊ณ ์ธ์ฑ ์ ๋๋ฆฌํฑ์ค์ ํ์ํ ๋ฐ์ดํฐ ํฌ์ธํธ๋ฅผ ํ๋ณดํ๋ ์ญํ ์ ์ํํฉ๋๋ค. ๋ฐ์ดํฐ๋ฅผ ์ธก์ ํ๊ธฐ ์ํด ๋ณธ ๋ฌธ์์ ์๋ด์ ๋ฐ๋ผ Wisetracker SDK๋ฅผ Android App์ ์ฐ๋ํ์ฌ ์ฃผ์๊ธฐ ๋ฐ๋๋๋ค.
1. ํ์ ์ค์
ํ์ ์ค์ ์ด๋ SDK๊ฐ ๋์ํ๊ธฐ ์ํด์ ๋ฐ๋์ ์ฑ์ ์ถ๊ฐ๋์ด์ผ ํ๋ ์ต์ํ์ ์ค์ ์ ๋งํฉ๋๋ค. ํ์ ์ค์ ์ ์ ์ฉํ๊ฒ ๋๋ฉด ์ธ์คํจ, ์ธ์ , ๋จ๋ง๊ธฐ ์ ๋ณด ๋ฑ์ ์ธก์ ํ ์ ์๊ฒ ๋ฉ๋๋ค.
์ฑ์ SDK ์ถ๊ฐ (JFrog Artifactory ์ด์ฉ)
ํ๋ก์ ํธ์ build.gradle ( root ํ์ผ ) ์ ์๋์ ๊ฐ์ด ์์ด์ฆํธ๋์ปค์ maven repository ์ฃผ์๋ฅผ ์ถ๊ฐํฉ๋๋ค.
์ ์ฅ์๊ฐ JFrog์์ Github์ผ๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค.
์ด์๋ฐ๋ผ JFrog๋ฅผ ์ด์ฉํ๋ ๋ฐฉ์์ 2023๋ 9์๊น์ง๋ง ์ ๊ณต๋๋ฉฐ, ์ดํ๋ถํฐ๋ ์๋ Github Package ์ด์ฉํ๋ ๋ฐฉ์์ผ๋ก ํ์ ๋ณ๊ฒฝ์ด ํ์ํฉ๋๋ค.
(๊ธฐ์กด JFrog์์ ์ฌ์ฉ๋๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋์ผํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํฌํจ๋์ด์์ต๋๋ค)
allprojects {
repositories {
google()
mavenCentral()
/* sdk repository url ์ถ๊ฐ */
maven { url 'https://wisetracker.jfrog.io/artifactory/wisetracker-gradle-release-local' }
}
}์ฑ์ SDK ์ถ๊ฐ (Github Package ์ด์ฉ)
ํ๋ก์ ํธ์ build.gradle ( root ํ์ผ ) ์ ์๋์ ๊ฐ์ด ์์ด์ฆํธ๋์ปค์ Repository ์ฃผ์๋ฅผ ์ถ๊ฐํฉ๋๋ค.
allprojects {
repositories {
google()
mavenCentral()
/* wisetracker sdk repository config */
maven {
def endPoint = "https://analytics.wisetracker.co.kr/console/android/sdk/github/credentials.do"
url = uri(new URL(endPoint+'?name=URI').text)
credentials {
username = new URL(endPoint+'?name=USER').text
password = new URL(endPoint+'?name=TOKEN').text
}
}
}
}import java.net.URL
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.androidApplication) apply false
}
allprojects {
repositories {
google()
mavenCentral()
/* wisetracker sdk repository config */
maven {
val endPoint = "https://analytics.wisetracker.co.kr/console/android/sdk/github/credentials.do"
val uriText = URL("$endPoint?name=URI").readText()
url = uri(uriText)
credentials {
username = URL("$endPoint?name=USER").readText()
password = URL("$endPoint?name=TOKEN").readText()
}
}
}
}์๋์ ๊ฐ์ ์ค๋ฅ ๋ฉ์์ง๊ฐ ๋ณด์ฌ์ง๋ ๊ฒฝ์ฐ, "Gradle Scripts"์ "settings.properties"ํ์ผ์ ์์ ํด์ผ ํฉ๋๋ค.
A problem occurred evaluating root project 'XXX'.
Build was configured to prefer settings repositories over project repositories but repository 'Google' was added by build file 'build.gradle'
...
dependencyResolutionManagement {
// =====================
// ์์ ๊ฐ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด
// ์๋ ํ ์ค์ ์ฃผ์์ฒ๋ฆฌํฉ๋๋ค.
// =====================
// repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
...
}
}
*/
..."app"๋ชจ๋๋จ์์ app/build.gradle ํ์ผ์ ์๋ dependencies์ ์๋์ ๊ฐ์ด Wisetracker SDK๋ฅผ ์ถ๊ฐํด์ฃผ์ธ์.
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
....
// SDK
implementation "com.sdk.wisetracker:base_module:latest.release"
implementation "com.sdk.wisetracker:new_dot_module:latest.release"
}plugins {
alias(libs.plugins.androidApplication)
}
android {
...
...
}
dependencies {
...
...
// SDK
implementation("com.sdk.wisetracker:base_module:latest.release")
implementation("com.sdk.wisetracker:new_dot_module:latest.release")
}AuthorizationKey ๋ฑ๋ก
ํ๋ก์ ํธ์ app/res/values/strings.xml ํ์ผ์ ์๋ ์ฝ๋๋ฅผ ์ถ๊ฐํฉ๋๋ค.
<string-array name="dotAuthorizationKey">
<item name="useMode">1</item>
<item name="serviceNumber">xxxxx</item> /* ์๋น์ค ๋ฒํธ ํ์ ๋ณ๊ฒฝ! */
<item name="expireDate">14</item>
<item name="isDebug">false</item>
<item name="isInstallRetention">true</item>
<item name="isFingerPrint">true</item>
<item name="accessToken"></item>
</string-array>์ถ๊ฐํ ์ฝ๋ ์ค serviceNumber์ value๋ฅผ ์ฌ๋ฐ๋ฅธ ๊ฐ์ผ๋ก ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค.
์์ด์ฆํธ๋์ปค ๋์๋ณด๋์ ๋ก๊ทธ์ธํ์ฌ ์ค์ > ์๋น์ค์ค์ ๋ฉ๋ด์์ '์๋น์ค๋ฒํธ' ํญ๋ชฉ์ ๊ธฐ์ฌ๋ ์ซ์๋ฅผ ํ์ธ ํ ๋ณต์ฌํ์ฌ serviceNumber ๊ฐ์ ๋ณ๊ฒฝ ํด ์ฃผ์ธ์.

HTTP ํต์ ํ์ฉ
ํ๋ก์ ํธ์ Target API๊ฐ API Level 28 ์ด์์ผ ๊ฒฝ์ฐ์ ์ ์ฉํ๋ ์ค์ ์ ๋๋ค. ์๋์ ๊ฐ์ด HTTP ํต์ ์ ํ์ฉํ๋ ๋ ๊ฐ์ง ์ค์ ์ ์ถ๊ฐํด์ฃผ์ธ์.
AndroidManifest.xml ์ค์
<!-- AndroidManifest.xml -->
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config" /* ์ถ๊ฐ */
android:theme="@style/AppTheme">app/res/xml/network_security_config.xml ์ค์
์ด ํ์ผ์ด ์์ผ๋ฉด ํด๋น ์์น์ ์๋ก ๋ง๋ค์ด์ฃผ์ธ์.
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">trk.analytics.wisetracker.co.kr</domain>
</domain-config>
</network-security-config>ํ๋ก๊ฐ๋(Proguard) ์ค์
ํ๋ก์ ํธ์ ํ๋ก๊ฐ๋๊ฐ ์ค์ ๋์ด ์๋ ๊ฒฝ์ฐ, ์์ด์ฆํธ๋์ปค(Wisetracker) SDK ๊ด๋ จ ์์ธ ์ค์ ์ด ํ์ํฉ๋๋ค. ํ๋ก๊ฐ๋ ์ค์ ํ์ผ ํ๋จ์ ์๋์ ๊ฐ์ด ์ฝ๋๋ฅผ ์ถ๊ฐํด์ฃผ์ธ์.
# app/proguard-rules.pro
# --- wisetracker ์ด๋ฆ/์ฝ๋ ๋ชจ๋ ๋ณด์กด(๋๋
ํ/์ถ์ ์ ์ธ) ---
-keepattributes *Annotation*,InnerClasses,EnclosingMethod,Signature
-keep class com.google.gson.** { *; }
-keep class com.sdk.wisetracker.** { *; }์ด๊ธฐํ
Application์ ์์๋ฐ๋ ํด๋์ค๊ฐ ์๋ Activity๋ฅผ ์์๋ฐ๋ ๊ธฐ๋ณธ ํ๋ฉด์ onCreate() ํจ์์ ์ ์ฉํด ์ฃผ์ธ์. ์ฌ๊ธฐ์ ๋งํ๋ ๊ธฐ๋ณธ ํ๋ฉด์ AndroidManifest.xml ํ์ผ์ ์ ์ธ๋ Activity ์ค, "android.intent.action.MAIN" ์ "android.intent.category.LAUNCHER" Intent-Filter ๊ฐ ์ ์ฉ๋ Activity๋ฅผ ์๋ฏธํฉ๋๋ค.
import com.sdk.wisetracker.new_dot.open.DOT;
import com.sdk.wisetracker.base.tracker.data.init.InitializeManager;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// SDK ์ด๊ธฐํ.
if (!InitializeManager.initComplete) {
DOT.initialization(this);
}
else if (getIntent() != null){
DOT.setDeepLink(getApplicationContext(), getIntent());
}
}
}import com.sdk.wisetracker.new_dot.open.DOT
import com.sdk.wisetracker.base.tracker.data.init.InitializeManager
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
...
// SDK ํธ์ถ
if (!InitializeManager.initComplete) {
DOT.initialization(this)
}
else if (getIntent() != null){
DOT.setDeepLink(getApplicationContext(), getIntent())
}
}
}์ดํธ๋ฆฌ๋ทฐ์
๋ฐ์ดํฐ ์ ๊ทผ
DOT.getAttributedInfo ํธ์ถ์ ํตํด ์์ด์ฆํธ๋์ปค ๋์๋ณด๋์์ ์์ฑํ ์ดํธ๋ฆฌ๋ทฐ์
๋งํฌ๋ฅผ ํตํด ์ฑ์ ์ค์นํ ์ ์ (non-organic)์ attribute ์ ๋ณด๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
โ ํ์ ์ฒดํฌ ์ฌํญ
Android SDK ์ต์ ๋ฒ์ ์ด ์ ์ฉ๋์ด์ผ ํฉ๋๋ค.
Android API ๊ฐ 26 ์ด์ ํ๊ฒฝ์์ ๋์ํฉ๋๋ค.
SDK ์ด๊ธฐํ ํจ์ DOT.initialization(this)ํธ์ถํ ์ดํ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!InitializeManager.initComplete) {
// SDK ํธ์ถ
DOT.initialization(this);
// attribute ์ ๋ณด๋ฅผ ์ถ์ถ
DOT.getAttributedInfo(new DOT.AttributedInfoCallback() {
@Override
public void doTask(Map<String, Object> result) {
WiseLog.d("current attribution data on main activity ( onCreate ) : " + result.toString());
// result ํ๋ผ๋ฏธํฐ๋ฅผ ํ์์ ๋ฐ๋ผ ์ฌ์ฉํฉ๋๋ค.
}
});
}
else if (getIntent() != null){
DOT.setDeepLink(getApplicationContext(), getIntent());
}
}
}result ํ๋ผ๋ฏธํฐ์ ํํ๋ ์๋์ ์์๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์.
(result ํ๋ผ๋ฏธํฐ ๋ฐ์ดํฐ๊ฐ ๋น์ด์๋ค๋ฉด Organic ์ผ๋ก ์๋ณ๋ ๊ฒฐ๊ณผ์ ๋๋ค.)
โ ์ฑ์ค์น(์์)
{
install_media="P1540365166967", >> ๊ด๊ณ ์ฑ๋
install_mediaNm="WISE_TEST1", >> ๊ด๊ณ ์ฑ๋๋ช
install_campaign="C1710215861051", >> ๊ด๊ณ ์บ ํ์ธ
install_campaignNm="WISETRACKER", >> ๊ด๊ณ ์บ ํ์ธ๋ช
install_medium="", >> ๊ด๊ณ ํ์
install_keyword="" >> ๊ด๊ณ ํค์๋
}โก ์ฑ์คํ(์์)
{
open_media="P1540365166967",
open_mediaNm="WISE_TEST1",
open_campaign="C1710215861051",
open_campaignNm="WISETRACKER",
open_medium="",
open_keyword=""
}์ด๋ฒคํธ ์ค์
โ ํ๋ฉด์ ํ ๋๋ ์ด๋ฒคํธ ๋ถ์์ ์ํ ์ ์ฉ ๋ฐฉ๋ฒ์ ํ๋ฌ๊ทธ์ธ ์ค์ ๋ฐ ์ด๊ธฐํ ์ดํ์ ์๋ ๋งํฌ๋ฅผ ํด๋ฆญํ๊ฑฐ๋, ์ข์ธก IN-APP EVENT ๋ฉ๋ด๋ฅผ ํตํด ๊ฐ์ด๋๋ฅผ ํ์ธํ์ค ์ ์์ต๋๋ค.
๐ํ์ด์ง ๋ถ์ ๊ฐ์ด๋๋ก ์ด๋ํ๊ธฐ
๐์ธ์ฑ ์ด๋ฒคํธ ์ค์ ์ผ๋ก ์ด๋ํ๊ธฐ
Hybrid App์ ์ํ ์ค์ ์ถ๊ฐ
Hybrid App์ธ ๊ฒฝ์ฐ์๋ง ์ ์ฉํ๋ฉด ๋๋ ์ค์ ์ผ๋ก, WebView๋ก ํ์ํ ์นํ์ด์ง ๋ด์์ ๋ฐ์ํ๋ ์ด๋ฒคํธ๋ฅผ ์ธก์ ํ๊ธฐ ์ํด ํ์ํฉ๋๋ค. ์น๋ทฐ๋ก ๋ถ๋ฌ์จ ํ์ด์ง๋ฅผ ๊ฐ์งํ ์ ์๋๋ก ๋ค์๊ณผ ๊ฐ์ด setWebView ํจ์๋ฅผ ํธ์ถํด์ฃผ์ธ์.
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView webView = findViewById(R.id.web_view);
...
// SDK ํธ์ถ
DOT.setWebView(webView);
}override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val webView : WebView = findViewById(R.id.web_view)
...
// SDK ํธ์ถ
DOT.setWebView(webView)
}๊ทธ๋ฆฌ๊ณ WebViewClient ์ ๊ฐ๊ฐ์ ์ฝ๋ฐฑ์ ์๋์ ๊ฐ์ด ์ ์ฉํด์ฃผ์ธ์.
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// 1. document ์ DOT ๊ฐ์ฒด ์ฃผ์
.
WiseLog.d("onPageStarted" + url );
DOT.injectSdkToHtmlDocument(view,true);
super.onPageStarted(view,url,favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
WiseLog.d("onPageFinished" + url );
DOT.injectJavascriptWithDomSearch(view,url,true);
super.onPageFinished(view, url);
}
});webView.webViewClient = object : WebViewClient() {
fun onPageStarted(view: WebView?, url: String, favicon: Bitmap?) {
// 1. document ์ DOT ๊ฐ์ฒด ์ฃผ์
.
WiseLog.d("onPageStarted$url")
DOT.injectSdkToHtmlDocument(view)
super.onPageStarted(view, url, favicon)
}
fun onPageFinished(view: WebView?, url: String) {
WiseLog.d("onPageFinished$url")
DOT.injectJavascriptWithDomSearch(view, url, true)
super.onPageFinished(view, url)
}
}2. ๊ณ ๊ธ ์ค์
๊ณ ๊ธ ์ค์ ์ด๋ ๋ฐ๋์ ์ ์ฉํ ํ์๋ ์์ง๋ง ์์ด์ฆํธ๋์ปค์ ํ์ฅ๋ ๋ถ์๊ธฐ๋ฅ์ ํ์ฉํ๊ธฐ ์ํด ์ถ๊ฐํด์ผ ํ๋ ์ค์ ์ ๋งํฉ๋๋ค. ํ์์ ๋ฐ๋ผ ์ ํ์ ์ผ๋ก ์ค์ ์ ์ถ๊ฐํด์ฃผ์๊ธฐ ๋ฐ๋๋๋ค.
App Link ์ค์
์ฑ ๋งํฌ ์ค์ ๊ฐ์ด๋๋ ๋ณ๋์ ๋ฌธ์์ ์ ๋ฆฌ๋์ด ์์ต๋๋ค.
App Link ์ค์ ๋ฅ๋งํฌ ์ค์
๋ฅ๋งํฌ๊ฐ ์ค์ ๋ url ์ ํตํด์ ์คํ๋ ์ด๋ฒคํธ๋ฅผ ๋ถ์ํฉ๋๋ค. AndroidManifest.xml ํ์ผ์์ ์ฑ์ ํ๊ฒฝ์ ๋ง์ถฐ ๋ฅ๋งํฌ๋ก ์คํ๋๋ Activity์ android:host, android:scheme ๊ฐ์ ์ค์ ํด ์ฃผ์ธ์.
โ๏ธ์์ด์ฆํธ๋์ปค ๋์๋ณด๋์์ ์์ฑํ ์ดํธ๋ฆฌ๋ทฐ์
๋งํฌ๋ฅผ ํตํด ํ
์คํธ ๋ฐ ๊ด๊ณ ์งํ์ ์งํํ๋ฉฐ, ๋ฅ๋งํฌ ํด๋ฆญ ์ ์์ด์ฆํธ๋์ปค ์๋ฒ๊ฐ ์ฑ์ ์ค์น ์ฌ๋ถ๋ฅผ ํ๋จํ์ฌ ๋์ํฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ ํํ์ "https://xxxx.page.link" ๋งํฌ๋ฅผ ํด๋ฆญํ๊ฒ ๋๋ฉด ํด๋น URL์ด ๊ฐ๋ฅดํค๋ ์น์ผ๋ก ์ด๋ํจ์ผ๋ก์จ ์์ด์ฆํธ๋์ปค๊ฐ ์์งํ์ฌ์ผ ํ๋ ๊ด๊ณ ํ๋ผ๋ฏธํฐ๊ฐ์ด ์ ์ค๋ ์ ์์ด, ์ฑ์ผ๋ก ๋ฐ๋ก ์ด๋ ๊ฐ๋ฅํ ๋ค์๊ณผ ๊ฐ์ ํํ์ Unique ํ ์ปค์คํ
์คํค๋ง๊ฐ ํ์ํฉ๋๋ค.
์ด๋ฏธ ๋ง๋ค์ด์ง ์ ๋๋ฒ์
๋งํฌ๊ฐ ์กด์ฌ ํ๋ค๋ฉด ์์ด์ฆํธ๋์ปค์์ ์ฌ์ฉํ ๋ฅ๋งํฌ ์ง์
์คํค๋ง ์ค์ ์ '์ถ๊ฐ' ํด ์ฃผ์ธ์. (๋ฅ๋งํฌ์คํค๋ง ์ค์ ์ถ๊ฐ์ ๋ค๋ฅธ ๋งํฌ์ ์ด๋ ํ ์ํฅ๋ ์ฃผ์ง ์์ต๋๋ค.)
<!-- ์์๋ wisetracker://wisetracker.co.kr ๋งํฌ๋ก ์ฑ ์ง์
๊ฒฝ์ฐ -->
<activity android:name="com.sample.DeepLinkActivity"
android:launchMode="singleTop" >
<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="wisetracker.co.kr"
android:scheme="wisetracker" />
</intent-filter>
</activity>์์ ์ํ ์ฝ๋์ ๊ฐ์ด AndroidManifest.xml์ ์ค์ ์ ๋ง์น์๊ฒ ๋์๋ฉด ๋ค์๊ณผ ๊ฐ์ ํํ์ ์ปค์คํ ์คํค๋ง๊ฐ ์ค์ ๋ ์ํ๊ฐ ๋ฉ๋๋ค.
wisetracker://wisetracker.co.kr
์ฌ๊ธฐ์ wisetracker:// ๋ถ๋ถ์ดScheme(ํน์ ํ๋กํ ์ฝ) ์
๋๋ค. ๊ฐ๋ฐ์๊ฐ ์ฑ์ ์ด Scheme๋ฅผ ์ธ ๊ฒ์ด๋ผ๊ณ ๊ฒฐ์ ํ๋ ๊ฒ์ด๋ฉฐ, ํด๋น Scheme๋ง ์ค์ ์ ํ์
๋ ๋ฉ๋๋ค. ์ด์ด์ wisetracker.co.kr ๋ถ๋ถ์ ํน์ ํ์ด์ง์ ๋๋ฌํ๋๋ก ๋ง๋ค๊ธฐ ์ํ host(ํน์ path or ๋๋ฉ์ธ) ์
๋๋ค.
๋ฅ๋งํฌ ๋ถ์
๋ฅ๋งํฌ๋ก ์คํ๋๋ Activity์ onCreate์ onNewIntent์ ์๋์ ๊ฐ์ด setDeepLink๋ฅผ ์ถ๊ฐํฉ๋๋ค.
public class DeepLinkActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* ์ค๋ต.. */
if (!InitializeManager.initComplete) {
DOT.initialization(this);
}
else if (getIntent() != null){
DOT.setDeepLink(getApplicationContext(), getIntent());
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
DOT.setDeepLink(getApplicationContext(), getIntent());
}
}class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
...
// SDK ํธ์ถ
if (!InitializeManager.initComplete) {
DOT.initialization(this)
}
else if (getIntent() != null){
DOT.setDeepLink(getApplicationContext(), getIntent())
}
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
DOT.setDeepLink(applicationContext, getIntent())
}
}๋ฅ๋งํฌ ์์ธ ์ฒ๋ฆฌ
์์ด์ฆํธ๋์ปค SDK๋ฅผ ์ ์ฉํ๊ณ , ๊ด๊ณ ๋ถ์์ ํ๊ณ ์ ํ๋ ๊ฒฝ์ฐ, ์์ด์ฆํธ๋์ปค ์์คํ ์์ ๋ฐ๊ธ๋ ๊ด๊ณ ๋ถ์ ๋งํฌ์ ์ํด์ ์ฑ์ ์คํํ๋ ๋ฅ๋งํฌ URL์ ๋ค์๊ณผ ๊ฐ์ด ๊ด๊ณ ๋ถ์ ๋ชฉ์ ์ ํ๋ผ๋ฏธํฐ๊ฐ ์ถ๊ฐ๋ ์ ์์ต๋๋ค.
ํนํ ์น์ฑ์ ๊ฒฝ์ฐ url ์ด๋ผ๋ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์น๋ทฐ์ ๋ก๋ฉ๋์ด์ง ์นํ์ด์ง url์ ์ ๋ฌํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์๋ฐ, ์ด์ ๊ด๋ จํ์ฌ ์๋์ ์ผ์ด์ค์๋ ๋ฌธ์ ๊ฐ ์๋์ง ๋ฐ๋์ ํ์ธํ์๊ธฐ ๋ฐ๋๋๋ค.
// ๊ธฐ์กด์ deeplink ์ ๊ด๊ณ ๋ถ์ ํ๋ผ๋ฏธํฐ๊ฐ ์ถ๊ฐ๋ ์์๋ฅผ ๋ณด์ฌ์ฃผ๊ณ ์์ต๋๋ค.
YOUR_SCHEMA://YOUR_HOST?url={YOUR_WEB_PAGE_URL}&trackId=M00200881641977334670
&w_start=h&_wtno=102&_wts=P1641977288745
... ์ค๊ฐ ์๋ต ...
&w_end=hDeffered Deep Link (์ง์ฐ๋ ๋ฅ๋งํฌ) ์ ์ฉ
๊ธฐ์กด์ DOT.initialization SDK ์ด๊ธฐํ ํจ์ ๋์ ์๋์ DOT.initializationForDeferredCallback ํจ์๋ฅผ ์ฌ์ฉํ์ฌ, ์์ ๋ ์ง์ฐ๋ ๋ฅ๋งํฌ์ ์ฒ๋ฆฌ๋ฅผ ์ํ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค.
// your code...
DOT.initializationForDeferredCallback(this, new Runnable() {
@Override
public void run() {
// deferred deeplink ์ ๋ณด๋ DOT.getDeferredUrl() ๋ก ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ฉฐ,
// ์ฑ์์๋ ํด๋น ๋ณ์๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์.
// 1. callback ์ด ํธ์ถ๋๋ ์์ ์ ์ฆ์ __deferredUrl ํ๋ฉด์ผ๋ก ์ด๋ ์ฒ๋ฆฌ. __deferredUrl ๊ฐ์ด nil ์ด๋ฉด ๋ฉ์ธ ํ๋ฉด์ผ๋ก ์ด๋ ์ฒ๋ฆฌ.
// 2. __deferredUrl ๋ณ์๊ฐ์ ์ด๋๊ฐ์ ์ ์ฅํ๊ณ , ํ์๊ฐ์
์ดํ, ๋ก๊ทธ์ธ์ด ์๋ฃ๋ ์ดํ๋ฑ๊ณผ ๊ฐ์ด ํ์ํ ์์ ์ ์ ์ฅ๋ ๊ฐ์ ๊บผ๋ด์ ์ด๋ ์ฒ๋ฆฌ.
// 3. ์ฌ์ฉ ๊ฐ๋ฅํ Deferred deeplink ์ ๋ณด๊ฐ ์๋ ๊ฒฝ์ฐ์๋, __deferredUrl ๊ฐ์ด ๋(NULL) ์ด ๋ ์ ์์์ ๊ณ ๋ คํ์ฌ ์ฌ์ฉ.
String __deferredUrl = DOT.getDeferredUrl();
WiseLog.d("current deferred url : " + __deferredUrl);
}
});
// your code...์์ ๊ฐ์ด ์ง์ฐ๋ ๋ฅ๋งํฌ์ ๋ํ ๋์ ์ฝ๋๊ฐ ์ ์ฉ๋ ์ดํ์ ์์ด์ฆํธ๋์ปค ๋์ฌ๋ณด๋์์ ์๋์ ๊ฐ์ด ์ดํธ๋ฆฌ๋ทฐ์ ๋งํฌ๋ฅผ ์์ฑํ์๋ค๊ณ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค.
์ง์ฐ๋ ๋ฅ๋งํฌ(๋ํผ๋ ๋ฅ๋งํฌ)๊ฐ ์ฌ์ฉ๋ ์ดํธ๋ฆฌ๋ทฐ์
๋งํฌ์ด๊ธฐ ๋๋ฌธ์ ๋ง์ฝ ์ฑ์ด ์ค์น๋์ด ์์ง ์์๋ ๊ฒฝ์ฐ๋ผ๋ฉด, ๋จผ์ ์ฑ ์ค์น๋ฅผ ์ํด ๋ง์ผ(๊ตฌ๊ธ์คํ ์ด, ์ฑ์คํ ์ด)์ผ๋ก ์ด๋๋๊ณ , ์ฑ ์ค์น ์ดํ์ ์ฑ์ ์คํ์ํค๊ฒ ๋๋ฉด String __deferredUrl ๋ณ์์ ์ค์ ํ ์ฑ ์คํ ๋งํฌ๊ฐ ๋ค์ด๊ฐ ์์์ ํ์ธํ ์ ์์ต๋๋ค. (์: wisetester://mainscreen)
๋ฐ๋ผ์ ๋ค์ด๊ฐ ์๋ (๋ํผ๋) ๋ฅ๋งํฌ ๊ฐ์ ๋ฐ๋ผ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ์ง ์ดํ ์ก์ ์ ๋ํด ๋์๋๋ ์ฝ๋๋ฅผ ๊ฐ๋ฐํด ์ฃผ์๋ฉด ๋ฉ๋๋ค.
Facebook ๊ด๊ณ ์ฑ๊ณผ ์ธก์
Facebook App Ads์ ํผํฌ๋จผ์ค๋ฅผ ์์ด์ฆํธ๋์ปค๋ก ์ธก์ ํ๋๋ฐ ํ์ํ ์ค์ ์ผ๋ก, Facebook SDK๊ฐ ์ฑ์ ์ถ๊ฐ๋์ด ์๋ ๊ฒฝ์ฐ์๋ง ์ค์ ์ ์ ์ฉํ ์ ์์ต๋๋ค.
๋น์ฆ๋์ค ์ธ์ฆ
Facebook Developer ์ฌ์ดํธ์ ์ฑ์ค์ -๊ธฐ๋ณธ์ค์ ์์ ๋น์ฆ๋์ค ์ธ์ฆ ์ฌ๋ถ๋ฅผ ํ์ธ ํด ์ฃผ์ธ์. ๋น์ฆ๋์ค ์ธ์ฆ์ด ์๋ฃ๋์ง ์์์ ๊ฒฝ์ฐ, ๋ฆฌํผ๋ฌ ์ ๋ณด๊ฐ ์์ ๋์ง ์์, facebook ๊ด๊ณ ์ฑ๊ณผ์ ๋ํ ์ธก์ ์ด ์ด๋ ต์ต๋๋ค.
์ค์ ์ ์ฉ
ํ๋ก์ ํธ์ app/res/values/strings.xml ํ์ผ์ ์๋ ์ค์ ์ ์ถ๊ฐํฉ๋๋ค.
<!-- facebook AppLinkData ์ฌ์ฉ ์ฌ๋ถ -->
<string name="useFacebookAppLinkData">Y</string>์ต์ด๋ก ์คํ๋๋ Activity์ onCreate์ ๋ค์ ์ฝ๋๋ฅผ ์ถ๊ฐํด ์ฃผ์ธ์.
import com.facebook.applinks.AppLinkData;
// call Facebook API
AppLinkData.fetchDeferredAppLinkData(getApplicationContext(), new AppLinkData.CompletionHandler() {
@Override
public void onDeferredAppLinkDataFetched(AppLinkData appLinkData) {
if (appLinkData == null) {
DOT.receiveFailFacebookReferrer(1);
return ;
}
Bundle bundle = appLinkData.getArgumentBundle();
if (bundle == null) {
DOT.receiveFailFacebookReferrer(2);
return;
}
DOT.setFacebookReferrer(bundle);
}
}); override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// SDK ์ด๊ธฐํ
DOT.initialization(this)
...
...
// call Facebook API
// Facebook ์ง์ฐ๋ ์ฑ ๋งํฌ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
AppLinkData.fetchDeferredAppLinkData(applicationContext) { appLinkData ->
// App Link ๋ฐ์ดํฐ๋ฅผ ํ์ธํ๊ณ ์ฒ๋ฆฌ
if(appLinkData == null){
DOT.receiveFailFacebookReferrer(1)
return@fetchDeferredAppLinkData
}else{
// App Link ๋ฐ์ดํฐ์์ ํ์ํ ์ ๋ณด ์ถ์ถ
val targetUri = appLinkData.targetUri
val bundle: Bundle? = appLinkData.argumentBundle
if (targetUri == null) {
DOT.receiveFailFacebookReferrer(2)
return@fetchDeferredAppLinkData
}
DOT.setFacebookReferrer(bundle)
}
}
}๋ฐ์ดํฐ ํ์ธ
Facebook์ App Ads Helper๋ก Deferred Deep Linking ์ ํ ์คํธ ํจ์ผ๋ก์จ ์ ์ค์ ์ด ์ฌ๋ฐ๋ฅด๊ฒ ์ ์ฉ ๋์๋์ง๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
์ค๋น์ฌํญ
Android ํ ์คํธ ๋จ๋ง๊ธฐ ํ๊ฒฝ
๋จ๋ง๊ธฐ์ Facebook ์ฑ์ ์ค์นํ๊ณ Facebook ๊ฐ๋ฐ์ ๊ณ์ ์ผ๋ก ๋ก๊ทธ์ธํด์ฃผ์ธ์.
๋จ๋ง๊ธฐ์ ํ ์คํธ ๋์ ์ฑ(๊ณ ๊ฐ์ฌ ์ฑ)์ด ์ค์น๋์ด ์๋ค๋ฉด ์ญ์ ํด์ฃผ์ธ์.
๊ฐ๋ฐ์ ๋ชจ๋์ USB ๋๋ฒ๊น ์ ํ์ฑํ ํด์ฃผ์ธ์.
๋ฐ์คํฌํ ํ๊ฒฝ
Android Studio๋ฅผ ์ค์นํด์ฃผ์ธ์.
USB๋ก ์ฐ๊ฒฐ๋ ํ ์คํธ ๋จ๋ง๊ธฐ์ log๋ฅผ Android Studio์ logcat์ผ๋ก ํ์ธํ ์ ์์ด์ผ ํฉ๋๋ค.
Facebook ์ค์
ํ ์คํธ ๋์ ์ฑ์ด Facebook Developer์ ๋ฑ๋ก๋์ด ์์ด์ผ ํฉ๋๋ค.
๊ฐ๋ฐ์ ๊ณ์ ์ผ๋ก ๋ก๊ทธ์ธํ์ฌ ํ ์คํธ๋ฅผ ์งํํฉ๋๋ค.
์ฑ ์ค์นํ ๊ด๊ณ ํ ์คํธ
https://developers.facebook.com -> ๋๊ตฌ -> ์ฑ ๊ด๊ณ ์ง์ ๋๊ตฌ ๋ฉ๋ด๋ก ์ด๋ํฉ๋๋ค.
(https://developers.facebook.com/tools/app-ads-helper/)
ํ ์คํธํ ์ฑ์ ์ ํํ ํ ํ์ด์ง ํ๋จ Developer Tool์ ๋ฅ๋งํฌ ํ ์คํธ๋ฅผ ํด๋ฆญํฉ๋๋ค.
PC์์ Android Studio๋ฅผ ์คํํ๊ณ ํ ์คํธ ๋จ๋ง๊ธฐ๋ฅผ USB๋ก ์ฐ๊ฒฐํ์ฌ ๊ด๋ จ ๋ก๊ทธ๋ฅผ logcat์ผ๋ก ํ์ธํ ์ ์๋๋ก ์ค๋นํฉ๋๋ค. ์ฑ์ด ์์ ํ Deep Link Referrer๋ฅผ logcat์์ ํ์ธํด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
Facebook ํ ์คํธ ํ์ด์ง๋ก ๋์๊ฐ๋๋ค. ์ฑ์ ์ปค์คํ ์คํค๋ง๋ฅผ Send Deep Link์ ์ ๋ ฅํ๊ณ Send to Android ๋ฅผ ํด๋ฆญํฉ๋๋ค. ์ด ๋ ์ ์ก์ง์ฐ์ ๋ฐ๋์ ์ฒดํฌ๋์ด ์์ด์ผ ํฉ๋๋ค.
'์ ์ก์ง์ฐ'์ ์ ํํ ๊ฒฝ์ฐ Facebook ์ฑ์ ์๋ฆผ์ ์์ ๋์ง ์์ง๋ง, ์๋์ ๊ฐ์ ํ์ ์ด ๋ฐ์ ํ์๋ค๋ฉด ์ธ์คํจ๋ฆฌํผ๋ฌ ์์ ์ ์ํ ์ค๋น๊ฐ ์๋ฃ ๋ ๊ฒ์ ๋๋ค.
์๋๋ก์ด๋ ์คํ๋์ค๋ฅผ ํตํด ํด๋น ์ฑ์ ์คํํ๊ณ ๋ก๊ทธ๋ฅผ ํ์ธ ํฉ๋๋ค. Facebook์ ์ ๋ ฅํ ์ปค์คํ ์คํค๋ง๊ฐ ์๋ ๊ทธ๋ฆผ์ฒ๋ผ logcat์์ ๋ณด์ธ๋ค๋ฉด
ํ์ด์ค๋ถ ์ฑ ์ค์น ๊ด๊ณ์ ๋ํ ๋ถ์์ด ๊ฐ๋ฅํฉ๋๋ค.
์ฑ ์ฐธ์ฌํ ๊ด๊ณ ํ ์คํธ
์ฑ ์ฐธ์ฌ ๊ด๊ณ ๋ฅผ ์งํํ๋ ๊ฒฝ์ฐ ์ด๋ฏธ ์ฑ์ ์ค์นํ ์ฌ์ฉ์๊ฐ ๊ด๊ณ ๋ฅผ ํด๋ฆญํ์ฌ ์ฑ์ ์คํํ๋ ์์ ์ ํ์ด์ค๋ถ ๊ด๊ณ ์ ๋ฑ๋กํ ๋ฅ ๋งํฌ๊ฐ์ด ๋์ํ๋์ง ์ฌ๋ถ๋ฅผ ํ์ธํ๋ฉด ๋ฉ๋๋ค.
์ฑ ์ฐธ์ฌ ๊ด๊ณ ๋ฑ๋ก ์ ์ฌ์ฉํ ๋ฅ ๋งํฌ๋ฅผ Send Deep Link ์์ญ์ ์ ๋ ฅ ํ Send to Android ๋ฒํผ์ ํด๋ฆญํฉ๋๋ค. ์ด ๋ ์ ์ก ์ง์ฐ๋ ๋ฐ๋์ ์ฒดํฌ ํด์ ๋์ด ์์ด์ผ ํฉ๋๋ค.
ํ ์คํธ ๋จ๋ง๊ธฐ์ Facebook ์ฑ์ ์๋ฆผ์ด ์ ์ก๋ฉ๋๋ค. ํด๋น ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ์ฑ์ ์คํํฉ๋๋ค.
Facebook์ ์ ๋ ฅํ ์ปค์คํ ์คํค๋ง๊ฐ ์๋ ๊ทธ๋ฆผ์ฒ๋ผ logcat์์ ๋ณด์ธ๋ค๋ฉด ํ์ด์ค๋ถ ์ฑ ๊ด๊ณ ์ ๋ํ ๋ถ์์ด ๊ฐ๋ฅํฉ๋๋ค.
Last updated
Was this helpful?