安卓 SDK 集成指南

 

视频指南

观看视频,详细了解集成过程。建议同时使用视频和下面的书面指南。

开始之前:集成SDK所需预置条件

按照集成Singular SDK的步骤操作:规划和先决条件

这些步骤是任何 Singular SDK 集成的先决条件。

1.将 SDK 添加到项目中

1.1 使用 Gradle 添加 SDK

注:从Gradle 7开始,Android建议在 settings.gradle 中使用集中的版本库声明而不是项目或模块级的 build.gradle 声明。

  1. settings.gradle 文件中添加 Singular SDK 仓库:

    dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
    google()
    mavenCentral()
    maven { url 'https://maven.singular.net/' }
    }
    }

    或在旧版本的 Gradle 中,在 project/build.gradle 文件中添加 Singular SDK 仓库:

    repositories {
            mavenCentral()
    maven { url 'https://maven.singular.net/' } }
  2. app/build.gradle 的依赖列表中添加 Singular 库:

    dependencies {
        implementation 'com.google.android.gms:play-services:6.5.87'
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        ...
        implementation 'com.singular.sdk:singular_sdk:12.5.5'
        ...
    }

    如果您的应用程序是通过三星 Galaxy Store 发布的,还需添加以下内容以支持三星 Galaxy Store 的install referrer:

    dependencies {
          ...
          implementation 'store.galaxy.samsung.installreferrer:samsung_galaxystore_install_referrer:4.0.0'
          ...
        }
  3. 如果已禁用 Singular SDK 的传递依赖关系,请app/build.gradle 中添加以下内容:

    dependencies {
    ... implementation 'com.android.installreferrer:installreferrer:2.2' implementation 'com.google.android.gms:play-services-appset:16.0.0' ... }
  4. 如果您的应用程序未实施 Google Play Services API 17.0.0 或更高版本,请在 app/build.gradle 文件中添加以下依赖关系:

    dependencies {
    ...
    implementation 'com.google.android.gms:play-services-ads-identifier:17.0.0+'
    ...
    }

注意:Gradle 1.x-2.x 用户应使用 "compile"(编译)而非 "implementation"(实施)来添加依赖关系。

1.2.不使用 Gradle 添加 SDK

手动下载 SDK
  1. 从页面顶部的链接下载 SDK。
  2. 解压 SDK 包,将 Singular.aar 添加到 Android 项目目录下的 libs 文件夹中。如果不存在,请在项目文件夹中创建名为 libs 的目录(通常位于 <project>/app/libs)。
使用 Maven 添加 SDK

将我们的 maven 仓库添加到项目的 pom.xml:

<project ...>
<repositories>
    <repository>
      <id>singular.net</id>
      <url>http://maven.singular.net/</url>
    </repository>
 </repositories>
</project>

添加依赖关系:

<dependency>
    <groupId>com.singular.sdk</groupId>
    <artifactId>singular_sdk</artifactId>
    <version>12.0.2</version>
</dependency>
使用 Eclipse 添加 SDK

您可以使用 Eclipse AAR 插件: gradle-eclipse-aar-plugin

如果不想使用该插件,请按照以下步骤操作:

  1. 解压缩 singular_sdk-12.5.5.aar。
  2. 将 classes.jar 重命名为 singular_sdk-12.5.5.jar(这是主 SDK jar)。
  3. 以任意喜欢的方式将 "com.android.installreferrer:installreferrer:2.2 "库添加到项目中。
  4. 将 AAR 中 AndroidManifest.xml 中的 BIND_GET_INSTALL_REFERRER_SERVICE 权限复制到您的 AndroidManifest.xml 中。
  5. 将 AAR 中 AndroidManifest.xml 中的 CHECK_LICENSE 权限复制到 AndroidManifest.xml 中。
使用 Proguard 添加 SDK

将以下代码行添加到您的 proguard.config 文件中:

-keep class com.singular.sdk.** { *; }
-keep public class com.android.installreferrer.** { *; }
# 如果你的APP在调用revenue接口时使用Google billing库,请将下面这一行代码的注释取消
#-keep public class com.android.billingclient.** { *; }

1.3.添加所需的权限

AndroidManifest.xml文件的 <manifest> 标记下添加这些权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="BIND_GET_INSTALL_REFERRER_SERVICE" />
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />

注意:如果您的应用程序是针对Android 12/API level 31 或更高版本构建的,请添加访问 Google Advertising ID 的权限:

<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
如果您集成了儿童 SDK,请勿添加此权限。

如果您的应用程序是通过 Samsung Galaxy Store 发布的,且目标机型为 Android 11 或更高版本,请添加以下内容以支持 Samsung Galaxy Store 的install referrer:

<queries>
<package android:name="com.sec.android.app.samsungapps" />
</queries>
注意:如果您的应用程序具有 android.permission.GET_TASKS 权限,则可能会在用户实际打开应用程序之前对其进行初始化。这可能会初始化 Singular SDK 并导致安装时间不一致。为防止出现这种问题,如果不需要该权限,请将其删除,或者将 Singular SDK 初始化调用移至代码中的其他地方,确保只有在用户首次打开应用程序后才被调用。

2.设置基本 SDK 集成

注意:在实施 Singular SDK 时,切记要遵守业务所在地区颁布的各种隐私法,包括 GDPR、CCPA和COPPA。更多信息,请参阅SDK 选择加入和选择退出实践

2.1.导入Singular库

要导入 Singular 库,请在 MainActivity 文件中添加以下导入内容:

Java (MainActivity.java) Kotlin (MainActivity.kt)
import com.singular.sdk.*;

2.2.构建配置对象

在初始化 SDK 之前,您必须创建一个 SingularConfig 对象。该对象将包含以下内容:

  1. 您的 SDK 密钥和 SDK Secret(要获取它们,请登录您的 Singular 账户,进入 "开发工具 > SDK 集成 > SDK 密钥 "菜单)。
  2. 根据需要设置SDK 偏好,此部分为可选设置。
  3. 支持 META 安装推荐人归属

    启用"元安装推荐人 "属性所需的 SDK 配置

    1. 在奇异配置对象中提供您的Facebook 应用程序 ID
      // 启用 META 安装引荐来源网址
      config.withFacebookAppId("在此插入您的 FACEBOOK 应用程序 ID");
    在哪里可以找到应用程序的 Facebook 应用程序 ID?

下面的代码示例创建了一个配置对象,并在初始化 Singular SDK 之前设置了常用配置选项。

下文将详细介绍这些选项以及如何对其进行自定义。

Java (MainActivity.java)Kotlin (MainActivity.kt)
@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
// 创建配置对象 SingularConfig config = new SingularConfig("SDK KEY", "SDK SECRET");

// 设置深度链接处理程序 config.withSingularLink( getIntent(), new SingularLinkHandler() { @Override public void onResolved(SingularLinkParams params) { String deeplink = params.getDeeplink(); String passthrough = params.getPassthrough(); boolean isDeferred = params.isDeferred(); // 在这里添加深度链接处理代码 } } );

Singular.init(context, config); ... }

 

SingularConfig 方法参考:查看所有可用的".with "选项

下表列出了 SingularConfig 对象的所有可用".with "方法,这些方法可用于为应用程序添加选项和功能。

你可以在下面的章节或 "高级选项"中找到每个功能的详细信息。

方法

说明

.withFacebookAppId(String facebookAppID)

配置 Facebook APP ID。"Meta Install Referrer "归因需要该 ID。

请参阅"在哪里可以找到应用程序的 Facebook App ID?

.withCustomUserId(String customId)

向 Singular 发送用户 ID。

.withSingularLink(getIntent(), SingularLinkHandler handler)

打开对Singular 跟踪链接中度链接的支持。

.withDDLTimeoutInSec (long timeout)

设置应用程序首次打开时,Singular 搜索延迟深层链接的时间长度。

.withDDLHandler (DeferredDeepLinkHandler handler)

启用传统跟踪链接(而非较新的 Singular 链接)的深度链接。

.withOpenURI (URI openURI)

从intent中获取 URI(以便在应用程序通过非 Singular 链接打开时处理深度链接)。

.withGlobalProperty(String key, String value, boolean overrideExisting)

将全局属性设置为给定值。键和值将与应用程序发送的任何事件/会话一起发送到 Singular。

.withSessionTimeoutInSec (long timeout)

设置会话超时。

.withFCMDeviceToken(String token)

设置第一次会话时要发送的 FCM 令牌。

.withLoggingEnabled ()

启用日志记录。

.withLogLevel (int level)

配置日志级别(默认为 Log.ERROR)。

2.3.添加深度链接支持

深度链接是指向应用程序内部特定内容的链接。当用户在安装了应用程序的设备上点击深层链接时,应用程序会打开并显示特定的产品或界面。 Singular跟踪链接可以包括深度链接和延迟深度链接 (更多信息请参阅我们的 深度链接常见问题 Singular链接常见问题)。

使用Singular链接启用深度链接

要为您的应用程序启用深度链接,请参阅支持Singular链接的先决条件

添加深度链接intent过滤器

在 AndroidManifest.xml 中添加如下intent过滤器,以便在activity中启用深层链接支持。如果您有多个activity需要通过深层链接打开,请为每个activity执行此操作。

注意:intent中不应配置“android:host“ 值。如果必须使用 “android:host“ 值:请确保在Singular应用配置页面中的scheme中包含host值,并在所有Singular深度链接中使用相同的 “android:host“ 值。

<activity> 
    <intent-filter>
        <data android:scheme="singular-example" />
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
    </intent-filter>
</activity>

处理深度链接

Singular SDK 提供了一种句柄处理机制,用于读取导致应用程序被打开的跟踪链接的详细信息。上面的 " 构建配置对象"示例代码中包含了 一个示例句柄处理程序。

注意:SingularLinkHandler 只有在应用是通过Singular链接打开时才会被调用(请参阅Singular链接 常见问题)。 其他类型的应用链接只有在您创建Singular配置对象时域包含在supportedDomains参数中时才会触发。 请参阅"处理非Singular深度链接"了解更多信息。

修改延迟深度链接超时阈值

默认情况下,当应用程序从特定设备向 Singular 发送第一个会话时,Singular 服务器会在其记录中查找是否存在与该设备匹配的延迟深度链接(请参阅 "什么是延迟深度链接? )如果找到延迟深度链接,则会将其发送回应用程序进行处理。但如果在 60 秒内没有找到递延深层链接,服务器就会停止搜索。

你可以在创建 SingularConfig 对象时调用withDDLTimeoutInSec来修改超时值。 下面的示例将超时值改为 30 秒:

SingularConfig config = new SingularConfig("SDK KEY", "SDK SECRET");
...
config.withDDLTimeoutInSec(30);
...
Singular.init(context, config);

处理非 Singular 深度链接

Singular SDK 支持非 Singular 服务的深度链接。这是为支持如 Google Ads 等合作伙伴衡量归因所必需的。

从 Android SDK 12.1.1 版开始,默认支持非 Singular 通用链接。如果您拥有新版本的 SDK,则无需采取任何措施即可支持第三方链接。

2.4.初始化 Singular

每次打开应用程序时都应初始化 Singular SDK,这是实现所有 Singular 归因功能的前提条件,同时也会向 Singular 发送一个新的用户会话(会话用于计算用户留存)。

要初始化 Singular,请使用以下代码:

Singular.init(context, config);
参数 描述
Context context 可以从应用程序类中传递thisgetApplicationContext()作为上下文。要从活动内部获取应用上下文,请调用currentActivity.getApplicationContext()
SingularConfig config 在前面步骤中创建的 SingularConfig 对象。

init 方法可以在应用程序中的任何位置调用,但必须在报告任何事件之前调用。我们建议在main activity的 onCreate 以及通过深度链接直接打开的任何activity中调用 init。

注意: 您必须在任何将通过深度链接打开的activity中初始化 Singular(请参阅实现深度链接)。因此,我们建议在应用程序的 onCreate 中初始化 Singular。如果在应用程序中初始化 Singular,然后又在activity中初始化,会导致 Singular 数据库中的会话重复。

2.5.向 Singular 发送用户 ID(可选)

您可以使用 Singular SDK 方法向 Singular 发送内部用户 ID。

注:如果使用Singular 的跨设备解决方案,则必须在所有平台上收集用户 ID。

  • 用户 ID 可以是任何标识符,但不能暴露 PII(个人身份信息),例如,不能使用用户的电子邮件地址、用户名或电话号码。Singular 建议使用仅对第一方数据唯一的哈希值。
  • 传递给Singular的用户ID值也应该是你在所有平台(Web/移动/PC/控制台/离线)上获取的相同的内部用户ID。
  • Singular 将在用户级导出、ETL 和内部 BI 回传(如果配置)中包含用户 ID。用户 ID 是第一方数据,Singular 不会与其他方共享。
  • 使用 Singular SDK 方法设置的用户 ID 值将一直存在,直到使用unsetCustomUserId 方法取消设置或卸载应用程序为止。关闭或重启应用程序不会取消设置用户 ID。

要设置用户 ID,请使用setCustomUserId 方法。要取消设置(例如,如果用户 "注销 "账户),请致电unsetCustomUserId

注意:如果多个用户使用一台设备,我们建议实施注销流程,为每次登录和注销设置取消设置用户 ID。

如果已经知道应用程序打开时的用户 ID,请在初始化 Singular SDK 之前调用setCustomUserId 。这样,Singular 就能从第一次会话中获得用户 ID。不过,在用户注册或登录之前,用户 ID 通常是不可用的。在这种情况下,请在注册流程完成后调用setCustomUserId

Singular.setCustomUserID 方法
说明 向 Singular 发送用户 ID。
签名 public void setCustomUserId(string customUserId)
使用示例
Singular.setCustomUserId("custom_user_id");
Singular.unsetCustomUserID 方法
说明 取消设置已发送至 Singular 的用户 ID。
签名 public void unsetCustomUserId()
使用示例
Singular.unsetCustomUserId();
可选:自定义用户 ID 设备映射

重要:此高级企业功能仅在特殊情况下可用。实施前请咨询 Singular 解决方案工程师

Singular 可以通过服务器到服务器集成接收额外的移动事件跟踪数据。要使用此功能,必须将用户 ID 映射到 Singular 的移动设备跟踪标识符。

注意:在初始化Singular SDK后或获得用户ID后,请尽快调用此方法。

Singular.setDeviceCustomUserId方法
说明 设置与登录相同的自定义用户 ID,并将其映射到 Singular 的跟踪标识符。
签名 public void setDeviceCustomUserId(string customUserId)
使用示例
Singular.setDeviceCustomUserId("custom_user_id");

2.6.实现全局属性(可选)

Singular SDK 允许你定义额外的自定义属性,以便与应用程序发送的每个会话和事件一起发送到 Singular 服务器。这些自定义属性可以表示用户信息、应用程序的模式或状态、或者其他任何你想要的信息。一旦设置了这些属性,它们就会作为数据维度出现在你的报告中,你可以用它们来细分数据

例如,如果您有一个游戏应用程序,您可以定义一个名为 "级别 "的属性,并将其初始设置为 "0"。应用程序发送的任何会话和事件都将带有 "Level":"0"。一旦用户等级提升,您就可以将该属性重置为 "1",以此类推。然后,您就可以获得按用户等级分列的报告,包括会话、事件计数和收入数据。

  • 最多可以定义5 个全局属性
  • 它们会在应用程序运行期间持续存在(使用您给定的最新值),直到您取消设置或用户卸载应用程序。
  • 每个属性的名称和值最长可包含200 个字符。如果您传递的属性名称或值较长,将被截断为 200 个字符。
  • 全局属性可在用户级导出回传中访问和使用。将来还会增加汇总报告支持。如果有任何疑问,或对全局属性支持的更新感兴趣,请联系 Singular 客户成功经理!

通过 SingularConfig 设置全局属性

在初始化 SDK 之前,你可以使用withGlobalProperty方法通过SingularConfig设置全局属性。

请注意,由于全局属性及其值会在应用程序运行期间持续存在,因此您要设置的属性可能已被设置为不同的值。使用 overrideExisting 参数可告诉 SDK 是否用新值覆盖现有属性。

withGlobalProperty 方法
说明 设置全局属性。
签名 withGlobalProperty(String key, String value, boolean overrideExisting)
使用示例
// 设置两个全局属性,覆盖任何已存在的全局属性值
SingularConfig config = new SingularConfig("SDK KEY", "SDK SECRET")
  .withGlobalProperty(“MyProperty”, “MyValue”, true)
  .withGlobalProperty(“AnotherProperty”, “AnotherValue”, true);

初始化后设置全局属性

在应用程序运行过程中的任何时候,使用以下方法设置、取消设置或检索全局属性。

Singular.setGlobalProperty 方法
说明

将全局属性设置为给定值。

注意

  • 如果该属性尚未存在,且已有 5 个其他全局属性,则不会添加该属性。
  • 如果属性已被设置,overrideExisting 参数将决定是否覆盖现有值。
  • 如果属性设置成功,该方法返回true,否则返回false
签名 public static bool setGlobalProperty(String key, String value, boolean overrideExisting)
使用示例
boolean result = Singular.setGlobalProperty(“MyProperty”, “MyValue”, true);
Singular.getGlobalProperties 方法
说明 以 Map 形式读取所有全局属性及其当前值。
签名 public static Map<String, String> getGlobalProperties()
使用示例
Map<String, String> map = Singular.getGlobalProperties();
Singular.unsetGlobalProperty 方法
说明 移除全局属性。
签名 public static void unsetGlobalProperty(String key)
使用示例
Singular.unsetGlobalProperty(“MyProperty”);
Singular.clearGlobalProperties 方法
说明 删除所有全局属性。
签名 public static void clearGlobalProperties()
使用示例
Singular.clearGlobalProperties();

3.跟踪事件和收入

3.1. 跟踪事件(无收入)

Singular 可以收集应用内事件的相关数据,帮助分析营销活动的效果并衡量关键绩效指标。例如,您的企业可能希望收集有关用户登录、注册、教程完成或游戏应用程序等级提升的数据。

什么是标准事件和属性?

Singular 支持各种标准事件。这些常用事件通常由广告网络支持,用于报告和优化。另一个优点是,当你使用标准事件名称时,Singular会自动识别并将其添加到事件列表中,而无需你手动定义。我们建议尽可能使用标准事件

发送到 Singular 的事件列表(附带属性)应由用户体验/营销/业务团队根据企业的营销关键绩效指标编制。业务团队可参考《如何跟踪应用内事件:Singular归因客户指南》。

您跟踪的每个事件都可以传递各种属性。请参阅每个事件的推荐标准属性

发送事件

在代码中,使用 eventJSON 或 event 方法向 Singular 发送事件(我们推荐使用 eventJSON 方法,以提高可读性)。

  • 对于标准事件,请使用Android SDK :标准事件和属性列表中的事件名称,例如sngTutorialComplete。请参阅下面的代码示例。
  • 如果您要发送任何自定义事件(您的组织想要测量的事件与 Singular 的标准事件不匹配),请使用符合限制条件的任意字符串。
Singular.eventJSON 方法
说明 以 JSONObject 格式向 Singular 报告用户事件及附加信息。
签名

Singular.eventJSON(String name, JSONObject args)

注: "args "是一个 JSONObject,包含一个或多个键值对。键是字符串,值可以是任何允许作为 JSONObject 值的类型。
使用示例
Java (MainActivity.java) Kotlin (MainActivity.kt)
// 示例 1:
// 发送标准事件sng_tutorial_complete并携带推荐的标准属性参数 JSONObject att = new JSONObject(); att.put(Attributes.sngAttrContent.toString(), <TUTORIAL NAME>); att.put(Attributes.sngAttrContentId.toString(), <CONTENT ID>); att.put(Attributes.sngAttrContentType.toString(), <TYPE OF CONTENT>); att.put(Attributes.sngAttrSuccess.toString(), <LOGIN SUCCESS VALUE>);
Singular.eventJSON(Events.sngTutorialComplete.toString(), att);
// 示例 2: // 发送名为 "bonus_points_earned"的自定义事件,携带自定义属性参数 JSONObject att = new JSONObject();
att.put("Points", 500); Singular.eventJSON("Bonus Points Earned", att);
Singular.event 方法
说明 向 Singular 报告用户事件,可提供或不提供附加信息。
签名

Singular.event(String eventName)
Singular.event(String eventName, Object... args)

注: "args "是一个或多个键值对(见下面的示例)。键是字符串,值可以是任何允许作为 JSONObject 值的类型(即 JSONObject、JSONArray、字符串、布尔、整型、长整型、双浮点数或 NULL)。

“args ”列表必须包含偶数个元素,否则事件将被 Singular 拒绝。

使用示例
Java (MainActivity.java)Kotlin (MainActivity.kt)
// 示例 1: 
// 发送标准事件sng_tutorial_complete并携带推荐的标准属性参数 Singular.event(Events.sngTutorialComplete.toString(), Attributes.sngAttrContent.toString(), <TUTORIAL NAME>, Attributes.sngAttrContentId.toString(), <CONTENT ID>, Attributes.sngAttrContentType.toString(), <TYPE OF CONTENT>, Attributes.sngAttrSuccess.toString(), <SUCCESS> ); // 示例 2:
// 发送名为"Subscribe" (sng_subscribe)的标准事件,不携带属性参数 Singular.event(Events.sngSubscribe.toString());
// 示例 3: // 发送名为 "bonus_points_earned"的自定义事件,携带自定义属性参数 Singular.event("Bonus Points Earned", "Points", 500);

注释

  • 我们强烈建议以英文传递事件名称和属性,以保证与第三方合作伙伴和分析解决方案(如果您计划使用它们)的兼容性。
  • 事件名称限制为 32 个 ASCII 字符。转换为 UTF-8 后,非 ASCII 字符的字符串必须小于 32 字节。
  • 所有属性和值总长度限制为 500 个 ASCII 字符。

3.2.跟踪收入

Singular可以收集通过应用程序获得的收入数据,以帮助分析营销活动的效果和投资回报率。Singular会通过报告、日志导出和回传等方式向您提供这些数据。

使用购买对象(Purchase Object)跟踪收入

向 Singular 报告收入事件时,我们建议传递从计费库(billing library)接收到的购买对象。这样做有两个好处:

  1. Singular 可以获得交易的所有详细信息,从而丰富 Singular 报告。
  2. Singular 可以从谷歌获得交易收据,用于在打击应用内欺诈时验证交易。

提醒

  • 自 2023 年 8 月 2 日起,所有新应用程序必须使用计费库版本 5 或更新版本。到 2023 年 11 月 1 日,现有应用程序的所有更新版本都必须使用计费库版本 5 或更高版本。了解更多信息。
  • 如果您的应用程序针对 Android 14 或更高版本,则必须更新至PBL 5.2.1PBL 6.0.1或更高版本。

使用revenuecustomRevenue方法报告事件。CustomRevenue允许你传递自定义事件名称,这样你就能在 Singular 报告中查看按不同类型收入事件分类的收入。

注:任何以不同货币上报的收入都将自动转换为贵组织在 Singular 账户中设置首选的货币类型

Singular.revenue 方法
说明 向 Singular 发送带有可选附加信息的收入事件。
签名

Singular.revenue(String currency, double amount, Object purchase)

注意

  • 传递对象时,必须是购买(Purchase)类型,否则 Singular 将获取不到收据信息。
  • 传递货币时应使用三个字母的 ISO 4217 货币代码,如 "USD"、"EUR "或 "INR"。
使用示例
// 向Singular发送收入事件,携带从Google Billing Library收到的购买对象 
Singular.revenue("USD", 5.50, purchase);
Singular.customRevenue 方法
说明 向 Singular 发送带有自定义事件名称和可选附加信息的收入事件。
签名

Singular.customRevenue(String eventName, String currency, double amount, Object purchase)

注意

  • 传递对象时,必须是购买(Purchase)类型,否则 Singular 将获取不到收据信息。
  • 传递货币时应使用三个字母的 ISO 4217 货币代码,如 "USD"、"EUR "或 "INR"。
使用示例
// 向Singular发送收入事件,携带自定义的事件名称以及购买对象
Singular.customRevenue("MyCustomRevenue", "USD", 
5.50, purchase);

不使用购买对象报告收入

虽然我们强烈建议按照上述方式报告收入事件,但您也可以使用revenuecustomRevenue而不传递购买对象。取而代之的是传递交易的货币类型和金额,以及可选的产品详细信息。

请注意,以这种方式报告收入事件时,Singular 无法获得购买收据,也就无法验证交易。

了解更多...
Singular.revenue 方法(不含购买对象)

说明

向 Singular 发送包含可选附加信息的收入事件。

签名

Singular.revenue(String currency, double amount, String productSKU, String productName, String productCategory, int productQuantity, double productPrice)

Singular.revenue(String currency, double amount)

注意:传递货币为三个字母的 ISO 4217 货币代码,如 "USD"、"EUR "或 "INR"。

使用示例

// 向Singular发送收入事件并携带商品信息
Singular.revenue("EUR", 5.00, "SKU1928375", 
"Reservation Fee", "Fee" , 1, 5.00); //向Singular发送收入事件,而不携带商品信息 Singular.revenue("USD", 5.50);
Singular.customRevenue 方法(不含购买对象)
说明 向 Singular 发送带有自定义事件名称和可选附加信息的收入事件。
签名

Singular.customRevenue(String eventName, String currency, double amount, String productSKU, String productName, String productCategory, int productQuantity, double productPrice)
Singular.customRevenue(String currency, double amount)

注意:传递货币为三个字母的 ISO 4217 货币代码,如 "USD"、"EUR "或 "INR"。

使用示例
// 向Singular发送带有自定义事件名称和商品详情的收入事件
Singular.customRevenue("MyCustomRevenue", "EUR", 5.00, 
"SKU1928375", "Reservation Fee", "Fee" , 1, 5.00); // 向Singular发送带有自定义事件名称的收入事件 Singular.customRevenue("MyCustomRevenue", "USD", 5.50);

3.3.混合事件跟踪(高级)

Singular 建议通过集成到应用程序中的 Singular SDK 发送所有事件和收入。不过,Singular 也可以从其他来源收集事件和收入。

任何非通过 Singular SDK 发送的事件都必须符合 Singular 的服务器到服务器事件文档要求,并提供匹配的设备标识符以正确归属事件。

重要

如果服务器到服务器事件请求中使用的设备标识符在 Singular 中没有匹配的设备标识符,就会出现差异。请注意以下可能性:

  • 如果事件请求是在 Singular SDK 从应用程序会话记录设备标识符之前收到的,那么该事件请求将被视为未知设备的 "第一次会话",Singular 将把该设备作为有机归属
  • 如果 Singular SDK 确实记录了设备标识符,但 Singular SDK 标识符与服务器到服务器事件请求中指定的设备标识符不同,那么事件将被错误归属

混合事件跟踪指南

从内部服务器发送事件

Singular可以收集来自服务器的收入数据,帮助分析营销活动的表现和投资回报率。

要求

  • 从应用内注册或登录事件中捕获并传递设备标识符,并将此数据与服务器上的用户 ID 一起存储。由于用户的设备标识符可能会发生变化,因此请确保在用户生成应用程序会话时更新标识符。这将确保服务器端事件归属于正确的设备。
  • 服务器端事件是平台特定的,只能使用与设备平台相匹配的设备标识符发送(如 iOS 设备的 IDFA 或 IDFV)。
  • 您可以使用 Singular 内部 BI 回传机制将事件实时推送到内部端点,以便更新服务器端的数据集。请参阅内部 BI 回传常见问题
  • 查看服务器到服务器集成指南中的"跟踪收入 "部分,了解详情。
从收入提供商发送事件
RevenueCatadapty等第三方提供商可以向Singular提供购买和订阅收入

请点击以下链接了解如何启用这些合作伙伴。

从分段发送事件

要使 Segment 能与 Singular SDK 并行发送事件到 Singular,必须在 Segment 中添加一个"云模式 "目的地。请点击此处查看我们的指南。

4.高级选项

4.1.创建短推荐人链接

注:此功能在 SDK 12.1.1+ 版本中可用。 一旦创建,短链接将在 30 天内保持有效。

使用短链接可将冗长、充满参数的Singular链接转换为更短、更安全的链接,方便共享。

通常情况下,您需要动态创建短链接,以便应用程序的用户可以与朋友分享,邀请他们使用应用程序。

要创建短链接,您需要

  • 指向应用程序下载的Singular链接(请参阅Singular链接常见问题)。
  • 要动态添加到链接中的任何参数(可用参数列表请参阅跟踪链接参数)。
  • 推荐用户的姓名和 ID,如果您希望跟踪新应用的安装情况,并追溯到共享链接的用户。

使用createReferrerShortLink方法创建短链接,如下例所示。

Java (MainActivity.java) Kotlin (MainActivity.kt)
// 创建JSON对象,其中包含要添加到Singular链接里的参数(如果这些参数尚不存在于链接的URL中)
JSONObject params = new JSONObject();       
try {
      params.put("channel","sms");
      params.put("another parameter","parameter value");
} catch (JSONException e) {
      e.printStackTrace();
}

Singular.createReferrerShortLink (
  "https://sample.sng.link/D52wc/cuvk?pcn=test", // 基础的Singular链接URL
  "Referrer Name",
  "Referrer ID",
  params,
  new ShortLinkHandler() { 
    @Override
      public void onSuccess(final String shortLinkURL) {
        view.post(new Runnable() {
          @Override
          public void run() {
            // 在此处添加用于链接共享的代码逻辑
          }   
        });
      }

@Override public void onError(final String error) { view.post(new Runnable() { @Override public void run() { // 添加错误处理逻辑,根据错误原因进行处理,例如:重新尝试、取消、修改入口参数等 } }); } });

4.2.添加广告收入归因支持

注:从 11.0.0 版开始,Singular 添加了通过 Singular SDK 设置广告收入归因的选项。 你仍然可以选择用老方法(使用 API 调用)设置广告收入归因,而不需要你更新应用程序中的 Singular SDK。

在 Singular SDK 中添加广告收入归因支持:

  1. 更新到最新版本的Singular SDK
  2. 根据您使用的广告收入数据聚合平台,在您的 Singular SDK 集成中添加相应的代码片段。

注:以三个字母的 ISO 4217 货币代码传递货币类型,如 "USD"、"EUR"、"INR"。

AdMob
  1. 注意: 此功能需要在您的 Admob 账户中启用。

    请参见 https://support.google.com/admob/answer/11322405#getstarted

KotlinJava
var mRewardedAd: RewardedAd? = null

override fun onAdLoaded(rewardedAd: RewardedAd) {
   mRewardedAd = rewardedAd
   mRewardedAd?.setOnPaidEventListener(object : OnPaidEventListener {
      override fun onPaidEvent(adValue: AdValue) {
         val impressionData: AdValue = adValue
         val data = SingularAdData(
            "AdMob",
            impressionData.currencyCode,
            impressionData.valueMicros / 1000000.0)
         Singular.adRevenue(data)
      }
  })
}
AppLovinMax
  1. 读取从 AppLovin MAX 的事件onMessageReceived 接收到的对象
KotlinJava
val message: AppLovinCommunicatorMessage? = null 
val adData: Bundle? = message?.messageData

adData?.let { bundle -
    val data = SingularAdData(
        "AppLovin",
        "USD",
        bundle.getDouble("revenue", 0.0)
    )
    Singular.adRevenue(data)
}
IronSource
  1. 读取从 IronSource 的事件OnImpressionSuccess接收到的对象
  2. 确保打开 IronSource 中的 ARM SDK Postbacks 标志
  3. 请参见https://developers.is.com/ironsource-mobile/general/ad-revenue-measurement-postbacks/#step-1
KotlinJava
val impressionData: ImpressionData? = null

impressionData?.let { data -
    val singularAdData = SingularAdData(
        "IronSource",
        "USD",
        data.revenue)
    Singular.adRevenue(singularAdData)
}
TradPlus
  1. 设置impressionDelegate
  2. TradPlusAdImpression回调中添加 Singular
KotlinJava
TradPlusSdk.setGlobalImpressionListener(
object : GlobalImpressionManager.GlobalImpressionListener { override fun onImpressionSuccess(tpAdInfo: TPAdInfo?) { if (tpAdInfo == null) return val revenue = tpAdInfo.ecpm.toDouble() / 1000 val data = SingularAdData(
"TradPlus",
"USD",
revenue) Singular.adRevenue(data) } })
其他(通用)
  1. 使用相关数据初始化SingularAdData对象
  2. 向 Singular 报告数据
KotlinJava
val data = SingularAdData(
"您的广告平台",
"货币代码",
9.90)
Singular.adRevenue(data)

4.3.卸载跟踪

要启用安卓应用程序的卸载跟踪功能,首先要在 Singular 平台上配置应用程序,详见 设置卸载跟踪。 然后按照以下说明操作。

注意:谷歌于 2018 年 4 月废弃了 GCM API。参照下文描述,使用 Firebase Cloud Messaging (FCM) 进行卸载跟踪。

I.与 FCM 集成:

要跟踪卸载,您可以使用 Firebase Cloud Messaging (FCM) 平台的服务。如果您尚未使用 FCM,请按照谷歌的说明 在 Android 上设置 Firebase Cloud Messaging 客户端应用程序

FCM 要求 ( )

FCM 客户端要求运行 Android 4.1 或更高版本的设备,同时安装 Google Play Store 应用程序,或运行 Android 4.1 并带有 Google API 的模拟器。请注意,这并不意味着您必须通过 Google Play Store 部署您的 Android 应用程序。

如果用户/设备运行的不是受支持的安卓版本,则无法进行Singular卸载跟踪。

II.更新 AndroidManifest.xml 文件:

更新 AndroidManifest.xml 文件,为应用程序添加必要的intent过滤器(用实现 Firebase 服务的类替换 MyFirebaseMessagingService):

<service android:name=".java.MyFirebaseMessagingService"
android:exported="false">
    <intent-filter>
        action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

III.注册并发送 FCM 设备令牌:

最后,在 OnCreate() 中初始化 SingularConfig 后设置 FCM 设备令牌,如下所示:

Singular.setFCMDeviceToken(String fcmDeviceToken);

4.4.在旧设备上收集Install Referrer

注意:Google 正在淘汰 install_referrer intent 广播。请参阅:还在使用 InstallBroadcast?在 2020 年 3 月 1 日前切换到 Play Referrer API

Install Referrer是 Singular 确定归属的最准确工具,此外还能帮助 Singular 检测和分析欺诈企图。它是 Google Play 商店提供的标识符,指向用户在安装应用程序之前点击的广告。

在安装了最新版 Google Play 商店的设备上,Singular SDK 会自动收集Install Referrer(因为 Singular 已集成了最新的Google Play Referrer API)。

在旧版设备上收集Install Referrer:

如果您已有install referrer接收器:

你的应用程序很可能已经有了一个广播接收器(BroadcastReceiver),可以接收来自 Android 的 INSTALL_REFERRER。

如果是这样,只需在 BroadcastReceiver 的onReceive方法中添加以下一行即可:

new SingularInstallReceiver().onReceive(context, intent);

例如,如果您现有的接收器名为 MyCustomInstallReceiver,它应该如下所示:

public class MyCustomInstallReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 将install referrer信息传递给Singular
        new SingularInstallReceiver().onReceive(context, intent);
        // ...
    }
}

如果没有其他install referrer接收器:

如果您的应用程序中没有任何install referrer接收器,只需在清单文件中的 <application> 标签中添加以下内容,即可让 Singular SDK 注册唯一的��收器:

<receiver android:exported="true" android:name="com.singular.sdk.SingularInstallReceiver">
    <intent-filter>
        <action android:name="com.android.vending.INSTALL_REFERRER" />
    </intent-filter>
</receiver>

4.5.管理会话

对于安卓API 14(Ice Cream Sandwich)及以上版本,Singular SDK可以自动处理会话管理。如果应用程序的 minSdkVersion 为 14 或更高,则无需为会话管理进行额外配。

修改会话超时阈值

默认情况下,如果应用程序在后台运行 60 秒或更长时间后才返回前台,SDK 就会注册一个新会话。

要更改超时值,请在初始化 SDK 前在SingularConfig对象中使用withSessionTimeoutInSec(<timeout in seconds>)方法。

例如

// 将会话超时阈值设置为120秒
SingularConfig config = new SingularConfig("SDK KEY", "SDK SECRET")
.withSessionTimeoutInSec(120); 

手动会话管理

如果你的应用程序的 minSdkVersion 低于 14,你需要在应用程序的每一个activity中调用 Singular's SDK 的两个会话处理方法(onActivityPausedonActivityResumed)来手动管理会话。

注: 如果你有一个自定义的通用基础activity类,所有其他activity都是从该类派生出来的,那么你可以将对 onActivityResumed 和 onActivityPaused 的调用放在通用activity的 "onResume 和 onPause 方法 "中。

Singular.onActivityResumed 方法
说明 在活动的 onResume 方法中调用此方法来管理 Singular 会话。
签名 public static void onActivityResumed()
使用示例
@Override
protected void onResume() {
    super.onResume();
    Singular.onActivityResumed();
    .... //其他代码
}
Singular.onActivityPaused 方法
说明 在活动的 onPause 方法中调用此方法来管理 Singular 会话。
签名 public static void onActivityPaused()
使用示例
@Override
protected void onPause() {
    super.onPause();
    Singular.onActivityPaused();
    .... //其他代码
}

4.6.使用 JavaScript 接口

Singular 提供了一个 JavaScript 接口,你可以使用该接口在应用程序的 javaScript 代码中调用 Singular SDK的功能。

例如,如果设置了 JavaScript 接口,就可以通过 JavaScript 代码向 Singular 发送事件,如下所示:

事件示例

SingularInterface.event('event');
SingularInterface.event('test',
JSON.stringify({"a1":"bar", "a2":"boo", "a3":"baz"}));

该接口支持以下 SDK 方法:

  • setCustomUserID
  • unsetCustomUserID
  • event
  • revenue

要启用 JavaScript接口,请在main activity中添加以下代码行,其中 "myWebView "是 webview 的名称。

SingularJSInterface singularJSInterfaceInstance = new SingularJSInterface(this);
singularJSInterfaceInstance.setWebViewId(R.id.webview);
myWebView.addjavascriptInterface(singularJSInterfaceInstance, "SingularInterface");

注意

  • 如果您有多个webview,请为每个webview都添加此代码。
  • 我们建议将代码放在应用程序的 onCreate 方法中。

您的 onCreate 方法可能如下所示:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    WebView myWebView = (WebView) this.findViewById(R.id.webview);
    WebSettings webSettings = myWebView.getSettings();
    webSettings.setjavaScriptEnabled(true);
    myWebView.loadUrl("file:///android_asset/index.html");

    SingularConfig config = new SingularConfig("SDK KEY", "SDK SECRET");
    Singular.init(this, config);
    SingularJSInterface singularJSInterfaceInstance = 
        new SingularJSInterface(this);
    singularJSInterfaceInstance.setWebViewId(R.id.webview);
    myWebView.addjavascriptInterface(singularJSInterfaceInstance,
        "SingularInterface");
}

4.7.收集 OAID(开放广告 ID)

在不使用 Google Play 的国家/地区,安卓设备没有谷歌广告 ID(GAID,在 Singular 中也称为 AIFA)。取而代之的是,设备可以提供一种名为 OAID(开放式广告标识符)的标识符,用于跟踪来自设备的会话和事件。

目前,华为和属于移动安全联盟(MSA)的品牌都在他们的设备上提供 OAID。

您的应用程序要收集 OAID,首先必须集成MSA SDK华为 OAID SDK。 您需要集成这两个 SDK,才能在所有提供 OAID 的平台上收集 OAID。

然后,要告诉 Singular SDK 使用 OAID 进行跟踪,请在初始化 Singular 之前,在配置对象中添加对方法withOAIDCollection的调用。

SingularConfig config = new SingularConfig("SDK KEY","SDK SECRET")
    .withOAIDCollection();
Singular.init(context, config);

Singular SDK 会自动检测设备是否有 OAID,以及应使用哪个 OAID SDK 收集标识符。

4.8.收集 IMEI 号码

如果您的应用程序在不使用 Google Play 的国家/地区发布,则设备没有 Google Advertising ID。在这种情况下,您可能需要收集设备的 IMEI(国际移动设备识别码)。

注意:如果使用 Google Play 服务,则不应收集 IMEI 号码,因为这违反了 Google Play 服务协议。

要收集 IMEI 号码:

在应用程序的 AndroidManifest.xml 文件中添加android.permission.READ_PHONE_STATE权限:

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

添加如下代码,以获取设备的 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();
}

要向 Singular 发送 IMEI 号码,请使用以下方法之一:

建议使用 在初始化 Singular SDK 之前,使用withIMEISingularConfig中设置 IMEI 号码,如下例所示。这样,Singular 就可以从第一次会话开始使用 IMEI 号码。

SingularConfig config = new SingularConfig("SDK KEY","SDK SECRET")
.withIMEI("537769845792516"); Singular.init(context, config);

要在 SDK 初始化后的任何代码中设置 IMEI 号码,请调用setIMEI

Singular.setIMEI 方法
说明 向 Singular 发送设备的 IMEI 号码。
签名 public void setIMEI(string IMEIString)
使用示例
Singular.setIMEI(IMEIString);

4.9.遵守数据隐私法

Singular提供隐私保护功能,以帮助您与任何可能遵守消费者隐私法(如GDPR和CCPA(加州消费者隐私法))的合作伙伴合作。 这些合作伙伴希望在最终用户同意共享其私人信息时得到通知。

如果你已经实施了一种征求用户同意共享其信息的方法,请使用limitDataSharing方法将用户的选择通知 Singular:

使用Singular.limitDataSharing(false)表示用户同意(选择加入)共享信息。

如果用户不同意,则使用 Singular.limitDataSharing(true)

Singular会在"用户隐私回传"User Privacy Postbacks)中使用限制数据分享(LimitDataSharing)功能,并将此信息传递给需要的合作伙伴,以遵守相关法规。更多信息请参阅"用户隐私和限制数据共享"

注意: 该方法的使用是可选的,但可能会有归属信息,只有在明确通知用户已选择的情况下,合作伙伴才会与Singular共享这些信息。

Singular.limitDataSharing方法
签名 Singular.limitDataSharing(boolean shouldLimitDataSharing)
说明 通知 Singular 用户同意(选择加入)共享私人数据。
使用示例
/* 用户同意(选择加入)共享私人数据 */
Singular.limitDataSharing(false);

遵守 GDPR 的其他方法

Singular SDK 提供了几种方法来帮助你遵守 GDPR 政策,并让 Singular 了解用户是否同意追踪。

Singular.trackingOptIn 方法
说明 通知 Singular 用户同意(选入)跟踪。
使用示例
Singular.trackingOptIn();
Singular.stopAllTracking 方法
说明

停止此用户在此应用程序中的所有跟踪活动。

注意:调用此方法将有效禁用 SDK,即使应用程序重新启动后也是如此(状态是持久的)!重新启用跟踪的唯一方法是调用 resumeAllTracking()。
使用示例
Singular.stopAllTracking();
Singular.resumeAllTracking 方法
说明 恢复此用户在此应用程序上的跟踪。
使用示例
Singular.resumeAllTracking();
Singular.isAllTrackingStopped 方法
说明 检查此应用程序中该用户的跟踪状态。如果使用 StopAllTracking() 停止了跟踪且未恢复,则返回 true。
使用示例
Singular.isAllTrackingStopped();