Android SDK - 高级选项

高级选项

配置高级 SDK 功能,包括安装 referrer 收集、会话管理、JavaScript 集成,以及用于 特殊用例的备用设备标识符。

安装 Referrer 收集(旧版设备)

概述

安装 referrer 通过识别用户在从 Google Play Store 安装您的应用之前点击的广告, 提供准确的归因。

已弃用功能: Google 已弃用 INSTALL_REFERRER intent 广播。请参阅 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 自动收集安装 referrer。仅在支持旧版设备时才需要手动配置。


与现有 receiver 集成

当您的应用已经有一个用于 INSTALL_REFERRER BroadcastReceiver 时,将安装 referrer 数据转发到 Singular。

实现:

在现有 receiver 的 onReceive 方法内添加对 SingularInstallReceiver 的调用。

Kotlin Java
class MyCustomInstallReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        // Forward install referrer to Singular
        SingularInstallReceiver().onReceive(context, intent)

        // Your existing logic
        // ...
    }
}

注册 Singular receiver

当您的应用没有现有的 INSTALL_REFERRER 处理程序时,配置 Singular 安装 referrer receiver。

AndroidManifest.xml 配置:

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)
Kotlin Java
// Set session timeout to 120 seconds (2 minutes)
val config = SingularConfig("SDK_KEY", "SDK_SECRET")
    .withSessionTimeoutInSec(120)

Singular.init(applicationContext, config)

超时值:

  • 默认值: 60 秒
  • 最小值: 0 秒(每次前后台切换都会创建一个新会话)
  • 推荐值: 根据应用使用模式,30-180 秒

手动会话管理 (API < 14)

对于 minSdkVersion 低于 14 的应用,通过在每个 activity 中调用生命周期方法来手动管理会话。

跳过本节,如果 您的 minSdkVersion 为 14(Ice Cream Sandwich)或更高,几乎可以肯定是这种情况。Singular SDK 在 API 14+ 上使用 ActivityLifecycleCallbacks 自动追踪会话,因此手动调用 onActivityResumed() / onActivityPaused() 是冗余的,并可能导致重复的会话事件。仅当您明确以早于 Android 4.0 的设备为目标时,才实现下面的代码。

实现

在每个 activity 的生命周期方法中调用 onActivityResumed() onActivityPaused() ,或者在 base activity 类中实现。

Kotlin Java
class MainActivity : AppCompatActivity() {

    override fun onResume() {
        super.onResume()
        Singular.onActivityResumed()
        // Your other code
    }

    override fun onPause() {
        super.onPause()
        Singular.onActivityPaused()
        // Your other code
    }
}

最佳实践: 如果您有一个通用的 base activity 类,请在 base 类的 onResume() onPause() 方法中实现这些调用,而不是在所有 activity 中重复代码。


适用于混合应用的 JavaScript 接口

概述

使用 SingularJSInterface 在基于 WebView 的混合应用中通过 JavaScript 代码启用 Singular SDK 功能。

支持的方法:

  • setCustomUserId: 设置自定义用户标识符
  • unsetCustomUserId: 移除自定义用户标识符
  • event: 追踪带或不带归因的事件
  • revenue: 追踪收入

设置 WebView 集成

为每个需要 Singular 功能的 WebView 在 activity 的 onCreate() 方法中配置 JavaScript 接口。

Kotlin Java
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")
}

多个 WebView:

  • 为应用中的每个 WebView 配置 JavaScript 接口
  • 为保持一致性,使用相同的接口名称("SingularInterface")
  • 为每个实例设置唯一的 WebView ID

JavaScript 使用

从在 WebView 中运行的 JavaScript 代码调用 Singular 方法。

追踪事件

JavaScript
// 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
    })
);

追踪收入

JavaScript
// Track revenue in USD
SingularInterface.revenue('USD', 9.99);

// Track revenue in other currencies
SingularInterface.revenue('EUR', 8.50);

管理自定义用户 ID

JavaScript
// 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 支持:

  • 华为设备: 华为专有的 OAID 实现
  • MSA 设备: Mobile Security Alliance 成员品牌(OPPO、Vivo、小米等)

前提条件

要在所有受支持的平台上收集 OAID,请同时集成 MSA SDK Huawei OAID SDK

启用 OAID 收集

配置 Singular SDK 以收集和使用 OAID 进行追踪。

Kotlin Java
val config = SingularConfig("SDK_KEY", "SDK_SECRET")
    .withOAIDCollection()

Singular.init(applicationContext, 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 收集。

添加必需权限

READ_PHONE_STATE 权限添加到您的 AndroidManifest.xml。

AndroidManifest.xml
<manifest>
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <application>
        <!-- Your application components -->
    </application>
</manifest>

获取 IMEI 号码

使用 TelephonyManager 获取设备 IMEI,并进行适当的 API 级别处理。

Kotlin Java
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")
}

将 IMEI 发送到 Singular

在 SDK 初始化期间配置 IMEI(推荐),或在初始化后动态设置。

选项 1:配置方法(推荐)

Kotlin Java
// Set IMEI during initialization
val config = SingularConfig("SDK_KEY", "SDK_SECRET")
    .withIMEI(imei)

Singular.init(applicationContext, config)

选项 2:运行时方法

Kotlin Java
// Set IMEI after initialization
Singular.setIMEI(imei)

最佳实践: 在 SDK 初始化之前在 SingularConfig 中设置 IMEI,以确保从第一个会话开始即可使用。仅当 IMEI 在初始化后才可用时, 才使用 setIMEI()