고급 옵션
설치 리퍼러 수집, 세션 관리, JavaScript 연동, 그리고 특수한 사용 사례를 위한 대체 디바이스 식별자를 포함한 고급 SDK 기능을 구성합니다.
설치 리퍼러 수집 (레거시 디바이스)
개요
설치 리퍼러는 유저가 Google Play Store에서 앱을 설치하기 전에 클릭한 광고를 식별하여 정확한 어트리뷰션을 제공합니다.
지원 중단된 기능:
Google은
INSTALL_REFERRER
인텐트 브로드캐스트를 더 이상 지원하지 않습니다.
Still Using InstallBroadcast? Switch to the Play Referrer API by March 1, 2020
을 참조하세요.
최신 Singular SDK 버전은 자동으로
Google Play Referrer API
를 사용합니다.
자동 수집:
최신 Google Play Store가 설치된 디바이스에서 Singular SDK는 Google Play Referrer API를 사용해 설치 리퍼러를 자동으로 수집합니다. 수동 구성은 레거시 디바이스 지원을 위해서만 필요합니다.
기존 리시버와 연동
앱에 이미
INSTALL_REFERRER
를 처리하는
BroadcastReceiver
가 있는 경우 설치 리퍼러 데이터를 Singular로 전달합니다.
구현:
기존 리시버의
onReceive
메서드 내부에서
SingularInstallReceiver
호출을 추가합니다.
class MyCustomInstallReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// Forward install referrer to Singular
SingularInstallReceiver().onReceive(context, intent)
// Your existing logic
// ...
}
}
public class MyCustomInstallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Forward install referrer to Singular
new SingularInstallReceiver().onReceive(context, intent);
// Your existing logic
// ...
}
}
Singular 리시버 등록
앱에 기존
INSTALL_REFERRER
핸들러가 없는 경우 Singular 설치 리퍼러 리시버를 구성합니다.
AndroidManifest.xml 구성:
<application>
<!-- Other application components -->
<receiver
android:name="com.singular.sdk.SingularInstallReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
</application>
권장 사항: 이 구성은 매우 오래된 디바이스를 지원하는 앱에서만 필요합니다. 최신 구현에서는 자동 Google Play Referrer API 연동을 사용해야 합니다.
세션 관리
자동 세션 관리
Singular SDK는 Android API 14 (Ice Cream Sandwich) 이상에서 추가 구성 없이 세션 관리를 자동으로 처리합니다.
기본 동작:
앱이 백그라운드로 60초 이상 이동한 후 다시 포어그라운드로 돌아오면 SDK는 새 세션을 등록합니다.
세션 타임아웃 구성
앱 사용 패턴에 맞게 세션 타임아웃 기간을 사용자 정의합니다.
메서드 시그니처:
SingularConfig.withSessionTimeoutInSec(int timeoutInSeconds)
// Set session timeout to 120 seconds (2 minutes)
val config = SingularConfig("SDK_KEY", "SDK_SECRET")
.withSessionTimeoutInSec(120)
Singular.init(applicationContext, config)
// Set session timeout to 120 seconds (2 minutes)
SingularConfig config = new SingularConfig("SDK_KEY", "SDK_SECRET")
.withSessionTimeoutInSec(120);
Singular.init(getApplicationContext(), config);
타임아웃 값:
- 기본값: 60초
- 최소값: 0초 (모든 백그라운드/포어그라운드 전환이 새 세션을 생성)
- 권장값: 앱 사용 패턴에 따라 30-180초
수동 세션 관리 (API < 14)
minSdkVersion
이 14 미만인 앱의 경우 각 액티비티에서 라이프사이클 메서드를 호출하여
세션을 수동으로 관리합니다.
이 섹션은 건너뛰세요:
사용 중인
minSdkVersion
이 14 (Ice Cream Sandwich) 이상인 경우 — 거의 대부분 해당됩니다. Singular
SDK는 API 14 이상에서
ActivityLifecycleCallbacks
를 사용해 세션을 자동으로 추적하므로
onActivityResumed()
/
onActivityPaused()
를 수동으로 호출하면 중복되며 세션 이벤트가 이중으로 발생할 수 있습니다.
Android 4.0 이전 디바이스를 명시적으로 타깃으로 하는 경우에만 아래
코드를 구현하세요.
구현
각 액티비티의 라이프사이클 메서드에서
onActivityResumed()
및
onActivityPaused()
를 호출하거나, 기본 액티비티 클래스에서 구현합니다.
class MainActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
Singular.onActivityResumed()
// Your other code
}
override fun onPause() {
super.onPause()
Singular.onActivityPaused()
// Your other code
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onResume() {
super.onResume();
Singular.onActivityResumed();
// Your other code
}
@Override
protected void onPause() {
super.onPause();
Singular.onActivityPaused();
// Your other code
}
}
모범 사례:
공통 베이스 액티비티 클래스가 있다면, 모든 액티비티에서 코드를 중복하지 말고
베이스 클래스의
onResume()
및
onPause()
메서드에서 이 호출을 구현하세요.
하이브리드 앱을 위한 JavaScript 인터페이스
개요
SingularJSInterface
를 사용해 WebView 기반 하이브리드 앱의 JavaScript 코드에서 Singular SDK 기능을
활성화합니다.
지원되는 메서드:
- setCustomUserId: 커스텀 유저 식별자 설정
- unsetCustomUserId: 커스텀 유저 식별자 제거
- event: 속성 유무에 관계없이 이벤트 트래킹
- revenue: 매출 트래킹
WebView 연동 설정
Singular 기능이 필요한 각 WebView에 대해 액티비티의
onCreate()
메서드에서 JavaScript 인터페이스를 구성합니다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Initialize Singular SDK
val config = SingularConfig("SDK_KEY", "SDK_SECRET")
Singular.init(this, config)
// Configure WebView
val myWebView = findViewById<WebView>(R.id.webview)
myWebView.settings.javaScriptEnabled = true
myWebView.loadUrl("file:///android_asset/index.html")
// Add Singular JavaScript interface
val singularJSInterface = SingularJSInterface(this)
singularJSInterface.setWebViewId(R.id.webview)
myWebView.addJavascriptInterface(singularJSInterface, "SingularInterface")
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize Singular SDK
SingularConfig config = new SingularConfig("SDK_KEY", "SDK_SECRET");
Singular.init(this, config);
// Configure WebView
WebView myWebView = findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.loadUrl("file:///android_asset/index.html");
// Add Singular JavaScript interface
SingularJSInterface singularJSInterface = new SingularJSInterface(this);
singularJSInterface.setWebViewId(R.id.webview);
myWebView.addJavascriptInterface(singularJSInterface, "SingularInterface");
}
여러 WebView:
- 앱의 각 WebView에 대해 JavaScript 인터페이스를 구성합니다
- 일관성을 위해 동일한 인터페이스 이름("SingularInterface")을 사용합니다
- 각 인스턴스에 고유한 WebView ID를 설정합니다
JavaScript 사용
WebView에서 실행되는 JavaScript 코드에서 Singular 메서드를 호출합니다.
이벤트 트래킹
// Simple event without attributes
SingularInterface.event('level_completed');
// Event with attributes (pass as JSON string)
SingularInterface.event('purchase_attempt',
JSON.stringify({
"item_name": "sword",
"item_category": "weapons",
"item_price": 9.99
})
);
매출 트래킹
// Track revenue in USD
SingularInterface.revenue('USD', 9.99);
// Track revenue in other currencies
SingularInterface.revenue('EUR', 8.50);
커스텀 유저 ID 관리
// Set custom user ID
SingularInterface.setCustomUserId('user_12345');
// Remove custom user ID
SingularInterface.unsetCustomUserId();
대체 디바이스 식별자
OAID (Open Advertising ID)
Open Advertising Identifier (OAID)를 사용해 Google Play가 없는 지역의 Android 디바이스에서 트래킹을 활성화합니다.
OAID 지원:
- Huawei 디바이스: Huawei의 독자적인 OAID 구현
- MSA 디바이스: Mobile Security Alliance 회원 브랜드 (OPPO, Vivo, Xiaomi 등)
사전 요구 사항
지원되는 모든 플랫폼에서 OAID를 수집하려면 MSA SDK 와 Huawei OAID SDK 를 모두 연동하세요.
OAID 수집 활성화
트래킹에 OAID를 수집하고 사용하도록 Singular SDK를 구성합니다.
val config = SingularConfig("SDK_KEY", "SDK_SECRET")
.withOAIDCollection()
Singular.init(applicationContext, config)
SingularConfig config = new SingularConfig("SDK_KEY", "SDK_SECRET")
.withOAIDCollection();
Singular.init(getApplicationContext(), config);
자동 감지:
- SDK는 디바이스에 OAID가 있는지 자동으로 감지합니다
- SDK는 디바이스에 따라 적합한 OAID SDK (MSA 또는 Huawei)를 선택합니다
- Amazon Advertising ID (AMID)는 추가 종속성 없이 자동으로 수집됩니다
IMEI (International Mobile Equipment Identity)
Google Play Services가 없는 지역의 디바이스에서 트래킹을 위해 디바이스 IMEI 번호를 수집합니다.
중요 중요: IMEI 수집은 Google Play Services 계약을 위반합니다. Google Play Store 외부에서 배포되는 앱 중 Google 서비스가 없는 지역에서만 IMEI 수집을 사용하세요.
필수 권한 추가
AndroidManifest.xml에
READ_PHONE_STATE
권한을 추가합니다.
<manifest>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application>
<!-- Your application components -->
</application>
</manifest>
IMEI 번호 가져오기
적절한 API 레벨 처리와 함께 TelephonyManager를 사용해 디바이스 IMEI를 가져옵니다.
val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
val imei: String? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
telephonyManager.imei
} else {
@Suppress("DEPRECATION")
telephonyManager.deviceId
}
// Validate IMEI before use
if (imei != null && imei.isNotEmpty()) {
// Send to Singular
Log.d("IMEI", "Retrieved: $imei")
} else {
Log.w("IMEI", "Failed to retrieve IMEI")
}
TelephonyManager telephonyManager =
(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String imei = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
imei = telephonyManager.getImei();
} else {
imei = telephonyManager.getDeviceId();
}
// Validate IMEI before use
if (imei != null && !imei.isEmpty()) {
// Send to Singular
Log.d("IMEI", "Retrieved: " + imei);
} else {
Log.w("IMEI", "Failed to retrieve IMEI");
}
Singular로 IMEI 전송
SDK 초기화 중에 IMEI를 구성하거나(권장) 초기화 이후에 동적으로 설정합니다.
옵션 1: 구성 메서드 (권장)
// Set IMEI during initialization
val config = SingularConfig("SDK_KEY", "SDK_SECRET")
.withIMEI(imei)
Singular.init(applicationContext, config)
// Set IMEI during initialization
SingularConfig config = new SingularConfig("SDK_KEY", "SDK_SECRET")
.withIMEI(imei);
Singular.init(getApplicationContext(), config);
옵션 2: 런타임 메서드
// Set IMEI after initialization
Singular.setIMEI(imei)
// Set IMEI after initialization
Singular.setIMEI(imei);
모범 사례:
첫 번째 세션부터 IMEI를 사용할 수 있도록 SDK 초기화 전에
SingularConfig
에서 IMEI를 설정하세요. 초기화 이후에 IMEI를 사용할 수 있게 된 경우에만
setIMEI()
를 사용하세요.