高级选项
配置高级 SDK 功能,包括安装推荐人收集、会话管理、JavaScript 集成和用于特殊用例的替代设备标识符。
安装推荐人收集(传统设备)
概述
安装推荐人可识别用户在 Google Play 商店安装应用程序前点击的广告,从而提供准确的归属。
已废弃:Google 弃用了INSTALL_REFERRER 意向广播。请参阅仍在使用 InstallBroadcast?在 2020 年 3 月 1 日前切换到 Play Referrer API。 现代 Singular SDK 版本会自动使用Google Play Referrer API。
自动收集:
只有支持传统设备时才需要手动配置。
与现有接收器集成
当您的应用程序已经有一个BroadcastReceiver 用于INSTALL_REFERRER 时,将安装推荐人数据转发给 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
// ...
}
}
注册奇异接收器
当您的应用程序没有现有的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(冰淇淋三明治)及以上版本的会话管理,无需额外配置。
默认行为:
当应用程序移至后台 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 的应用程序,可通过调用每个活动中的生命周期方法手动管理会话。
重要:只有针对低于 14 级(冰淇淋三明治)Android API 的应用程序才需要手动会话管理。 现代应用程序可跳过本节。
执行
在每个活动的生命周期方法中调用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 接口
概述
在基于 WebView 的混合应用程序中,使用SingularJSInterface 的 JavaScript 代码启用 Singular SDK 功能。
支持的方法
- setCustomUserId:设置自定义用户标识符
- unsetCustomUserId: 删除自定义用户标识符:移除自定义用户标识符
- 事件跟踪带或不带属性的事件
- revenue: 收入跟踪收入
设置 WebView 集成
在活动的onCreate() 方法中为每个需要 Singular 功能的 WebView 配置 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(开放式广告标识符)
使用开放式广告标识符 (OAID),在无 Google Play 地区的 Android 设备上启用跟踪功能。
支持 OAID:
- 华为设备:华为专有的 OAID 实现
- MSA 设备:移动安全联盟成员品牌(OPPO、vivo、小米等
前提条件
集成MSA SDK和华为 OAID SDK,以便在所有支持的平台上收集 OAID。
启用 OAID 收集
配置 Singular SDK 以收集和使用 OAID 进行跟踪。
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 或华为
- 自动收集亚马逊广告 ID(AMID),无需额外依赖
IMEI(国际移动设备标识)
收集设备 IMEI 号码,以便在没有 Google Play 服务的地区对设备进行跟踪。
重要警告:收集 IMEI 会违反 Google Play 服务协议。仅用于在无 Google 服务地区的 Google Play Store 之外分发的应用程序。
添加所需权限
在 AndroidManifest.xml 中添加READ_PHONE_STATE 权限。
<manifest>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application>
<!-- Your application components -->
</application>
</manifest>
获取 IMEI 号码
使用 TelephonyManager 以适当的 API 级别处理获取设备 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");
}
将 IMEI 发送至 Singular
在 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);
最佳做法:在 SDK 初始化之前在SingularConfig中设置 IMEI,以确保从第一个会话开始就可用。只有当 IMEI 在初始化后可用时,才使用setIMEI() 。