外观
安卓SDK
Zeus SDK 安卓 接入指南
SDK信息
- SDK 版本:1.0.0
一、环境要求
宿主工程必须满足下表。compileSdk / targetSdk 可以更高,minSdk 不能低于 21。
| 项 | 版本 |
|---|---|
| JDK | 11 |
| Gradle | 7.5.1 |
| AGP | 7.4.2 |
| minSdk | 24 |
| compileSdk | 34 |
| targetSdk | 36 |
二、Gradle 配置
AAR 不带传递依赖。拷贝哪个 AAR,就必须声明对应 Maven 依赖。
模块关系:
| AAR | 能力 | 是否必选 |
|---|---|---|
core / data / ui / sdk | 初始化、账号、支付、埋点、设备信息 | 必选 |
plugin-adjust | Adjust 归因 | 可选 |
plugin-applovin | AppLovin MAX 广告 + UMP | 可选 |
plugin-facebook | Facebook 登录/ 广告分析 | 可选 |
plugin-firebase | Firebase / Google 登录 / Crashlytics | 可选 |
2.1 拷贝 AAR
将 aar 放到** 应用模块 **的 libs/,例如 app/libs/:
text
app/libs/
├── core-release.aar # 必须
├── data-release.aar # 必须
├── ui-release.aar # 必须
├── sdk-release.aar # 必须
├── plugin-adjust-release.aar # 可选
├── plugin-applovin-release.aar # 可选
├── plugin-facebook-release.aar # 可选
├── plugin-firebase-release.aar # 可选2.1 仓库配置
保证能解析 Google / Maven Central。若工程已用 dependencyResolutionManagement,加在 settings 里即可,不要再在模块里重复声明仓库。
Kotlin DSL(settings.gradle.kts):
text
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}Groovy(settings.gradle):
text
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}2.3 依赖配置
Kotlin DSL(app/build.gradle.kts)
gradle
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}
android {
compileSdk = 34
defaultConfig {
minSdk = 24
targetSdk = 36
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
// Zeus 核心 AAR
implementation(files("libs/core-release.aar"))
implementation(files("libs/data-release.aar"))
implementation(files("libs/ui-release.aar"))
implementation(files("libs/sdk-release.aar"))
// --- 核心传递依赖(去重后)---
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.22")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.1")
implementation("io.insert-koin:koin-core:3.4.3")
implementation("io.insert-koin:koin-android:3.4.3")
implementation("io.ktor:ktor-client-core:2.3.12")
implementation("io.ktor:ktor-client-logging:2.3.12")
implementation("io.ktor:ktor-client-content-negotiation:2.3.12")
implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.12")
implementation("io.ktor:ktor-client-cio:2.3.12")
implementation("io.ktor:ktor-client-auth:2.3.12")
implementation("io.ktor:ktor-client-okhttp:2.3.12")
implementation("androidx.annotation:annotation-experimental:1.4.0")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.cardview:cardview:1.0.0")
implementation("androidx.datastore:datastore-preferences:1.0.0")
implementation("co.touchlab:kermit:1.2.2")
implementation("com.google.android.gms:play-services-ads-identifier:18.0.1")
implementation("com.android.billingclient:billing:9.1.0")
}**注意:**纯 Java 宿主可以不 apply org.jetbrains.kotlin.android,但仍必须保留 kotlin-stdlib 等运行时依赖。
Groovy(app/build.gradle)
gradle
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdk 34
defaultConfig {
minSdk 24
targetSdk 36
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
// Zeus 核心 AAR
implementation files('libs/core-release.aar')
implementation files('libs/data-release.aar')
implementation files('libs/ui-release.aar')
implementation files('libs/sdk-release.aar')
// --- 核心传递依赖(去重后)---
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.9.22'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3'
implementation 'org.jetbrains.kotlinx:kotlinx-datetime:0.4.1'
implementation 'io.insert-koin:koin-core:3.4.3'
implementation 'io.insert-koin:koin-android:3.4.3'
implementation 'io.ktor:ktor-client-core:2.3.12'
implementation 'io.ktor:ktor-client-logging:2.3.12'
implementation 'io.ktor:ktor-client-content-negotiation:2.3.12'
implementation 'io.ktor:ktor-serialization-kotlinx-json:2.3.12'
implementation 'io.ktor:ktor-client-cio:2.3.12'
implementation 'io.ktor:ktor-client-auth:2.3.12'
implementation 'io.ktor:ktor-client-okhttp:2.3.12'
implementation 'androidx.annotation:annotation-experimental:1.4.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.datastore:datastore-preferences:1.0.0'
implementation 'co.touchlab:kermit:1.2.2'
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
implementation 'com.android.billingclient:billing:9.1.0'
}2.4 可选插件依赖
在 2.3 的 dependencies { } 里按产品追加。拷贝了哪个 AAR,就加对应块;未接的插件不要拷 AAR,也不要加依赖。
核心已声明的 coroutines / koin / serialization / ads-identifier 等不必重复;下面只列各插件额外需要的 Maven 坐标。
2.4.1、Adjust
Kotlin DSL:
gradle
implementation(files("libs/plugin-adjust-release.aar"))
implementation("com.adjust.sdk:adjust-android:5.6.0")
implementation("com.android.installreferrer:installreferrer:2.2")Groovy:
groovy
implementation files('libs/plugin-adjust-release.aar')
implementation 'com.adjust.sdk:adjust-android:5.6.0'
implementation 'com.android.installreferrer:installreferrer:2.2'2.4.1、AppLovin
2.4.1.1 仓库配置
Mintegral / Pangle 不在 Maven Central。只接 AppLovin 时才需要这两条。
Kotlin DSL(settings.gradle.kts):
gradle
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url = uri("https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea") }
maven { url = uri("https://artifact.bytedance.com/repository/pangle") }
}
}Groovy(settings.gradle):
gradle
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea" }
maven { url "https://artifact.bytedance.com/repository/pangle" }
}
}2.4.1.2 依赖配置
Kotlin DSL:
gradle
implementation(files("libs/plugin-applovin-release.aar"))
implementation("androidx.lifecycle:lifecycle-process:2.2.0")
implementation("com.applovin:applovin-sdk:13.2.0")
implementation("com.applovin.mediation:google-adapter:23.6.0.0")
implementation("com.applovin.mediation:vungle-adapter:7.4.3.0")
implementation("com.applovin.mediation:facebook-adapter:6.20.0.0")
implementation("com.applovin.mediation:mintegral-adapter:17.1.81.0")
implementation("com.applovin.mediation:bytedance-adapter:8.3.0.4.1")
implementation("com.applovin.mediation:unityads-adapter:4.16.0.0")
implementation("com.google.android.gms:play-services-base:18.7.2")
implementation("com.google.android.ump:user-messaging-platform:2.1.0")Groovy:
groovy
implementation files('libs/plugin-applovin-release.aar')
implementation 'androidx.lifecycle:lifecycle-process:2.2.0'
implementation 'com.applovin:applovin-sdk:13.2.0'
implementation 'com.applovin.mediation:google-adapter:23.6.0.0'
implementation 'com.applovin.mediation:vungle-adapter:7.4.3.0'
implementation 'com.applovin.mediation:facebook-adapter:6.20.0.0'
implementation 'com.applovin.mediation:mintegral-adapter:17.1.81.0'
implementation 'com.applovin.mediation:bytedance-adapter:8.3.0.4.1'
implementation 'com.applovin.mediation:unityads-adapter:4.16.0.0'
implementation 'com.google.android.gms:play-services-base:18.7.2'
implementation 'com.google.android.ump:user-messaging-platform:2.1.0'google-adapter 保持 23.6.0.0(对齐 compileSdk 34)。unityads-adapter 不要升到 4.21+,该版本用 Kotlin 2.1 编译,会和当前 Kotlin 1.9 冲突。
2.4.1、Facebook
Kotlin DSL:
gradle
implementation(files("libs/plugin-facebook-release.aar"))
implementation("com.facebook.android:facebook-core:18.0.3")
implementation("com.facebook.android:facebook-login:18.0.3")Groovy:
groovy
implementation files('libs/plugin-facebook-release.aar')
implementation 'com.facebook.android:facebook-core:18.0.3'
implementation 'com.facebook.android:facebook-login:18.0.3'2.4.1、Firebase
Kotlin DSL:
gradle
implementation(files("libs/plugin-firebase-release.aar"))
implementation(platform("com.google.firebase:firebase-bom:32.8.1"))
implementation("com.google.firebase:firebase-messaging")
implementation("com.google.firebase:firebase-analytics")
implementation("com.google.firebase:firebase-crashlytics")
implementation("com.google.firebase:firebase-auth")
implementation("com.google.firebase:firebase-installations")
implementation("com.google.android.gms:play-services-auth:20.7.0")Groovy:
groovy
implementation files('libs/plugin-firebase-release.aar')
implementation platform('com.google.firebase:firebase-bom:32.8.1')
implementation 'com.google.firebase:firebase-messaging'
implementation 'com.google.firebase:firebase-analytics'
implementation 'com.google.firebase:firebase-crashlytics'
implementation 'com.google.firebase:firebase-auth'
implementation 'com.google.firebase:firebase-installations'
implementation 'com.google.android.gms:play-services-auth:20.7.0'2.5 Firebase Gradle 插件
仅在对接 Firebase 插件 时需要。Crashlytics Gradle 插件只能加在 最终应用模块 上,不能打进 AAR。缺了会在启动时闪退:IllegalStateException: The Crashlytics build ID is missing。同时把与包名匹配的 google-services.json 放到应用模块根目录(与 build.gradle 同级)。
2.5.1、根工程声明插件版本
Kotlin DSL(根 build.gradle.kts):
gradle
plugins {
id("com.google.gms.google-services") version "4.4.2" apply false
id("com.google.firebase.crashlytics") version "2.9.9" apply false
}Groovy(根 build.gradle,经典 classpath 写法):
groovy
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.4.2'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.9'
}
}或 plugins DSL:
gradle
plugins {
id 'com.google.gms.google-services' version '4.4.2' apply false
id 'com.google.firebase.crashlytics' version '2.9.9' apply false
}2.5.2、应用模块 apply
Kotlin DSL(app/build.gradle.kts):
gradle
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.gms.google-services")
id("com.google.firebase.crashlytics")
}Groovy(app/build.gradle):
gradle
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
}Crashlytics Gradle 插件 3.x 需要 AGP 8.1+,当前 SDK 是 AGP 7.4.2,不要升到 3.x。不接
plugin-firebase就不要加这两套插件和google-services.json。
三、SDK 参数配置
3.1、核心必填配置
SDK 通过(strings.xml)读取字符串配置,可在宿主应用模块创建 zeus_strings.xml进行配置
xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 必填:API 基址(末尾不要 /) -->
<string name="api_base_url" translatable="false">https://sdkapi.zeusai.dev</string>
</resources>缺省键会读成空字符串,不会因此编译失败;但 api_base_url 为空时网络请求会失败。
3.2、可选插件配置
拷贝了对应 plugin-*-release.aar 时才需要按需拷贝下方的键值并替换具体的参数内容
xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- ════ Adjust 归因(plugin-adjust) ════ -->
<string name="adjust_token" translatable="false">imr86...</string>
<!-- ════ AppLovin MAX 广告(plugin-applovin) ════ -->
<string name="applovin_max_sdk_key" translatable="false">3l6R_KZPq...</string>
<string name="applovin_max_app_open_ad" translatable="false">28f2...</string>
<string name="applovin_max_banner_ad" translatable="false">0fab...</string>
<string name="applovin_max_inter_ad" translatable="false">9735...</string>
<string name="applovin_max_reward_ad" translatable="false">624b...7</string>
<string name="applovin_max_native_ad" translatable="false">5e78...</string>
<!-- ════ Firebase / Google 登录(plugin-firebase) ════ -->
<string name="firebase_app_id" translatable="false">1:863071:a648b...</string>
<string name="google_client_id" translatable="false">8630....</string>
<!-- ════ Facebook 登录(plugin-facebook) ════ -->
<string name="facebook_app_id" translatable="false">610127403506312</string>
<string name="fb_login_protocol_scheme" translatable="false">fb6101...</string>
<string name="facebook_client_token" translatable="false">ce5a243d...</string>
<!-- ════ AdMob(AppLovin 中介常用) ════ -->
<string name="admob_app_id" translatable="false">ca-app-pub-x...</string>
<!-- ════ 合规链接(GDPR 弹窗) ════ -->
<string name="privacy_policy_url" translatable="false">https://www...</string>
<string name="terms_of_service_url" translatable="false">https://www...</string>
</resources>四、AndroidManifest 配置
4.1、核心必填配置
在应用模块 AndroidManifest.xml 的 <application> 上指定 SDK Application:
xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:name="com.zeus.sdk.ZeusApplication"
... >
</application>
</manifest>若宿主已有自定义 Application,需要继承 改为 ZeusApplication,并在 onCreate 里先 super.onCreate();
4.2、可选插件Manifest
4.2.1、Facebook
xml
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true">
<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:scheme="@string/fb_login_protocol_scheme" />
</intent-filter>
</activity>
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id" />
<meta-data
android:name="com.facebook.sdk.ClientToken"
android:value="@string/facebook_client_token" />4.2.2、AdMob / AppLovin
xml
<meta-data
xmlns:tools="http://schemas.android.com/tools"
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="@string/admob_app_id"
tools:replace="android:value" />五、API 接口对接
5.1、公共类型
SdkOption
init接口参数
kotlin
data class SdkOption(
val dev: Boolean, // true = 沙盒 / 测试
val appId: Int, // 我方分配的 App ID
val lang: String = "en", // 语言
val gdpr: Boolean = false, // 是否走 GDPR/UMP(发欧洲建议 true)
val loginBrand: String? = null, // 登录页品牌文案(有 UI 门面)
val debug: Boolean = false, // 第三方 SDK 调试;dev=false 时强制 false
)SdkResult<T>
通用返回包装
| 字段 | 说明 |
|---|---|
status | HTTP 状态,成功为 200 |
code | 业务码,成功为 0 |
message | 提示文案 |
data | 业务数据,失败时常为 null |
PayProductType
IN_APP:消耗型内购SUBSCRIPTION:自动续期订阅NON_RENEWING_SUBSCRIPTION:非续期订阅(主要给 Apple)
SdkLoginResp
登录成功 data
| 字段 | 类型 | 说明 |
|---|---|---|
token | String | 用户 token |
userId | Long | 用户 ID |
nickname | String | 昵称 |
email | String | 邮箱 |
bindAuths | List<String> | 已绑定三方类型 |
isNew | Boolean | 是否新用户 |
loginType | String | guest / google / facebook / apple 等 |
SdkBindThirdResp
绑定成功 data
| 字段 | 类型 | 说明 |
|---|---|---|
nickname | String | 昵称 |
email | String | 邮箱 |
bindAuths | List<String> | 绑定后的三方列表 |
SdkPayResult
支付成功 data
| 字段 | 类型 | 说明 |
|---|---|---|
orderId | String | 订单 ID |
skuId | String | SKU |
storeTransactionId | String | Apple transaction id |
SdkPendingPurchase
无 UI 查询待补单 data 元素
| 字段 | 类型 | 说明 |
|---|---|---|
skuId | String | SKU |
productType | PayProductType | 商品类型 |
purchaseToken | String | Google token |
originalJson | String | Google 原始 JSON |
jwsRepresentation | String | Apple JWS |
storeTransactionId | String | Apple transaction id |
SdkAdFormat
广告变现参数
| 枚举值 | 说明 |
|---|---|
APP_OPEN | 开屏广告 |
BANNER | Banner广告 |
INTERSTITIAL | 插屏广告 |
REWARDED | 激励视频广告 |
NATIVE | 原生广告 |
5.2、Activity 回调转发
Google / Facebook 登录等需转发
Kotlin:
kotlin
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
SDK.onActivityResult(requestCode, resultCode, data)
// 或 SdkHeadless.onActivityResult(requestCode, resultCode, data)
}Java:
java
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
SDK.INSTANCE.onActivityResult(requestCode, resultCode, data);
// 或 SdkHeadless.INSTANCE.onActivityResult(requestCode, resultCode, data);
}5.3、 有UI SDK
入口:com.zeus.sdk.api.SDK。账号相关会按服务端配置弹出登录页 / 欢迎浮窗 / 绑定页。
接口:init
kotlin
fun init(ctx: Any, config: SdkOption, callback: (SdkResult<Unit>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 当前 Activity |
config | SdkOption | 是 | 见 5.1 |
callback | (SdkResult<Unit>) -> Unit | 是 | 主线程回调;data 一般为 Unit |
接口:login
kotlin
fun login(ctx: Any, callback: (SdkResult<SdkLoginResp>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 用于展示登录 UI / 三方授权 |
callback | (SdkResult<SdkLoginResp>) -> Unit | 是 | 成功时 data 为 SdkLoginResp |
SDK 内部按配置编排游客 / Token / 三方,可能弹登录页。
接口:bindThird
kotlin
fun bindThird(ctx: Any, callback: (SdkResult<SdkBindThirdResp>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 展示绑定页 / 授权页 |
callback | (SdkResult<SdkBindThirdResp>) -> Unit | 是 | 成功时 data 为 SdkBindThirdResp |
接口:switchAccount
kotlin
fun switchAccount(ctx: Any, callback: (SdkResult<Unit>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 切号流程宿主 Activity |
callback | (SdkResult<Unit>) -> Unit | 是 | 成功无业务 data |
接口:logout
kotlin
fun logout(ctx: Any, callback: (SdkResult<Unit>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 当前 Activity |
callback | (SdkResult<Unit>) -> Unit | 是 | 登出结果 |
接口:purchase
kotlin
fun purchase(
ctx: Any,
skuId: String,
productType: PayProductType,
metadata: String? = null,
callback: (SdkResult<SdkPayResult>) -> Unit,
)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 拉起商店支付的 Activity |
skuId | String | 是 | 商品 SKU(与商店后台一致) |
productType | PayProductType | 是 | IN_APP / SUBSCRIPTION / NON_RENEWING_SUBSCRIPTION |
metadata | String? | 否 | 透传元数据,常用作 CP 订单号;默认 null |
callback | (SdkResult<SdkPayResult>) -> Unit | 是 | 成功时 data 为 SdkPayResult |
若 data.clientSendReward == true,必须再调 finishPurchase。
接口:processPendingPurchases
kotlin
fun processPendingPurchases(ctx: Any, callback: (SdkResult<List<SdkPayResult>>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 当前 Activity |
callback | (SdkResult<List<SdkPayResult>>) -> Unit | 是 | 成功时 data 为已处理的支付结果列表 |
有 UI 门面为一步完成(查询 + 验单处理)。
接口:finishPurchase
kotlin
fun finishPurchase(ctx: Any, req: SdkFinishPurchase, callback: (SdkResult<Unit>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 当前 Activity |
req | SdkFinishPurchase | 是 | 完整支付上下文,见 5.1;推荐 payResult.toFinishPurchase(productType) |
callback | (SdkResult<Unit>) -> Unit | 是 | 确认结果 |
接口:trackEvent
kotlin
fun trackEvent(name: String, parameters: Map<String, String> = emptyMap())| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | String | 是 | 事件名 |
parameters | Map<String, String> | 否 | 事件参数,默认空 Map |
接口:getUser
kotlin
fun getUser(): SdkLoginResp?接口:getConfig
kotlin
fun getConfig(): SdkInitResp?接口:sdkAd
kotlin
fun sdkAd(): SdkAdApi?接口:sdkInfo
kotlin
fun sdkInfo(): SdkInfoApi?调用示例
Kotlin
kotlin
import com.zeus.sdk.api.SDK
import com.zeus.sdk.api.SdkAdFormat
import com.zeus.sdk.api.SdkAppLovinAdListener
import com.zeus.sdk.api.SdkOption
import com.zeus.sdk.api.isSuccess
import com.zeus.sdk.pay.PayProductType
import com.zeus.sdk.pay.toFinishPurchase
SDK.init(
this,
SdkOption(
dev = true,
appId = 10000,
lang = "en",
gdpr = false,
loginBrand = "ZeusAI",
debug = true,
),
) { result ->
if (!result.isSuccess()) return@init
}
SDK.login(this) { result ->
if (result.isSuccess()) {
val user = result.data
}
}
SDK.bindThird(this) { }
SDK.switchAccount(this) { }
SDK.logout(this) { }
SDK.purchase(this, "test_sku_001", PayProductType.IN_APP, metadata = null) { result ->
val pay = result.data ?: return@purchase
if (pay.clientSendReward) {
SDK.finishPurchase(this, pay.toFinishPurchase(PayProductType.IN_APP)) { }
}
}
SDK.processPendingPurchases(this) { }
SDK.trackEvent("level_complete", mapOf("level" to "3"))
val userId = SDK.getUser()?.userId
val androidId = SDK.sdkInfo()?.getAndroidId()
SDK.sdkAd()?.setAdListener(object : SdkAppLovinAdListener {
override fun onAdLoaded(format: SdkAdFormat) {}
override fun onUserRewarded(format: SdkAdFormat, label: String, amount: Int) {}
})
SDK.sdkAd()?.preloadAd(SdkAdFormat.INTERSTITIAL)
if (SDK.sdkAd()?.isAdReady(SdkAdFormat.INTERSTITIAL) == true) {
SDK.sdkAd()?.showInterstitialAd("home")
}Java
java
import java.util.Collections;
import java.util.Map;
import com.zeus.sdk.api.SDK;
import com.zeus.sdk.api.SdkAdApi;
import com.zeus.sdk.api.SdkAdFormat;
import com.zeus.sdk.api.SdkAppLovinAdListener;
import com.zeus.sdk.api.SdkOption;
import com.zeus.sdk.api.SdkResultKt;
import com.zeus.sdk.data.models.SdkLoginResp;
import com.zeus.sdk.datas.SdkPayResult;
import com.zeus.sdk.pay.PayProductType;
import com.zeus.sdk.pay.SdkFinishPurchaseKt;
// 在 Activity 内调用;this 为当前 Activity
SDK.INSTANCE.init(
this,
new SdkOption(true, 10000, "en", false, "ZeusAI", true),
result -> {
if (!SdkResultKt.isSuccess(result)) {
return null;
}
return null;
}
);
SDK.INSTANCE.login(this, result -> {
if (SdkResultKt.isSuccess(result)) {
SdkLoginResp user = result.getData();
}
return null;
});
SDK.INSTANCE.bindThird(this, result -> null);
SDK.INSTANCE.switchAccount(this, result -> null);
SDK.INSTANCE.logout(this, result -> null);
SDK.INSTANCE.purchase(this, "test_sku_001", PayProductType.IN_APP, null, result -> {
SdkPayResult pay = result.getData();
if (pay == null) {
return null;
}
if (pay.getClientSendReward()) {
SDK.INSTANCE.finishPurchase(
this,
SdkFinishPurchaseKt.toFinishPurchase(pay, PayProductType.IN_APP),
finishResult -> null
);
}
return null;
});
SDK.INSTANCE.processPendingPurchases(this, result -> null);
Map<String, String> params = Collections.singletonMap("level", "3");
SDK.INSTANCE.trackEvent("level_complete", params);
Long userId = SDK.INSTANCE.getUser() != null
? SDK.INSTANCE.getUser().getUserId()
: null;
String androidId = SDK.INSTANCE.sdkInfo() != null
? SDK.INSTANCE.sdkInfo().getAndroidId()
: "";
SdkAdApi ad = SDK.INSTANCE.sdkAd();
if (ad != null) {
ad.setAdListener(new SdkAppLovinAdListener() {
@Override
public void onAdLoaded(SdkAdFormat format) {}
@Override
public void onAdLoadFailed(SdkAdFormat format, String errorMessage) {}
@Override
public void onAdDisplayed(SdkAdFormat format) {}
@Override
public void onAdHidden(SdkAdFormat format) {}
@Override
public void onAdClicked(SdkAdFormat format) {}
@Override
public void onUserRewarded(SdkAdFormat format, String label, int amount) {}
@Override
public void onAdExpired(SdkAdFormat format) {}
});
ad.preloadAd(SdkAdFormat.INTERSTITIAL);
if (ad.isAdReady(SdkAdFormat.INTERSTITIAL)) {
ad.showInterstitialAd("home");
}
}5.4、无UI SDK
入口:com.zeus.sdk.api.SdkHeadless。不弹 SDK ui/screens;登录 / 绑定由宿主选择原子接口。
接口:init
kotlin
fun init(ctx: Any, config: SdkOption, callback: (SdkResult<Unit>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 当前 Activity |
config | SdkOption | 是 | 见 5.1;loginBrand 无 UI 下基本不用 |
callback | (SdkResult<Unit>) -> Unit | 是 | 初始化结果 |
接口:guestLogin
kotlin
fun guestLogin(ctx: Any, callback: (SdkResult<SdkLoginResp>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 当前 Activity |
callback | (SdkResult<SdkLoginResp>) -> Unit | 是 | 成功 data 为 SdkLoginResp |
接口:tokenLogin
kotlin
fun tokenLogin(ctx: Any, callback: (SdkResult<SdkLoginResp>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 当前 Activity |
callback | (SdkResult<SdkLoginResp>) -> Unit | 是 | 用本地已存 token 自动登录 |
如果token登录失败返回code = 401时候,宿主应根据上次登录类型调用对应的登录接口。
无本地有效 token 时会失败,宿主应改调 guestLogin / thirdLogin 等。
接口:thirdLogin
kotlin
fun thirdLogin(ctx: Any, platform: String, callback: (SdkResult<SdkLoginResp>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 拉起三方授权的 Activity |
platform | String | 是 | SdkLoginPlatform.GOOGLE / FACEBOOK / APPLE |
callback | (SdkResult<SdkLoginResp>) -> Unit | 是 | SDK 完成授权 + 登录后回调 |
接口:partnerLogin
kotlin
fun partnerLogin(ctx: Any, partnerUserId: String, callback: (SdkResult<SdkLoginResp>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 当前 Activity |
partnerUserId | String | 是 | 合作方侧用户 ID |
callback | (SdkResult<SdkLoginResp>) -> Unit | 是 | 登录结果 |
接口:bindThird
kotlin
fun bindThird(ctx: Any, platform: String, callback: (SdkResult<SdkBindThirdResp>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 拉起授权的 Activity |
platform | String | 是 | 目标平台,见 SdkLoginPlatform |
callback | (SdkResult<SdkBindThirdResp>) -> Unit | 是 | 绑定结果 |
接口:logout
kotlin
fun logout(ctx: Any, callback: (SdkResult<Unit>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 当前 Activity |
callback | (SdkResult<Unit>) -> Unit | 是 | 登出结果 |
接口:purchase
kotlin
fun purchase(
ctx: Any,
skuId: String,
productType: PayProductType,
metadata: String? = null,
callback: (SdkResult<SdkPayResult>) -> Unit,
)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 拉起商店支付的 Activity |
skuId | String | 是 | 商品 SKU(与商店后台一致) |
productType | PayProductType | 是 | IN_APP / SUBSCRIPTION / NON_RENEWING_SUBSCRIPTION |
metadata | String? | 否 | 透传元数据,常用作 CP 订单号;默认 null |
callback | (SdkResult<SdkPayResult>) -> Unit | 是 | 成功时 data 为 SdkPayResult |
若 data.clientSendReward == true,必须再调 finishPurchase。
接口:queryPendingPurchases
kotlin
fun queryPendingPurchases(ctx: Any, callback: (SdkResult<List<SdkPendingPurchase>>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 当前 Activity |
callback | (SdkResult<List<SdkPendingPurchase>>) -> Unit | 是 | 只查询、不验单;data 为待补单列表 |
接口:processPendingPurchases
kotlin
fun processPendingPurchases(ctx: Any, callback: (SdkResult<List<SdkPayResult>>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 当前 Activity |
callback | (SdkResult<List<SdkPayResult>>) -> Unit | 是 | 宿主确认后调用;成功 data 为处理结果 |
接口:finishPurchase
kotlin
fun finishPurchase(ctx: Any, req: SdkFinishPurchase, callback: (SdkResult<Unit>) -> Unit)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ctx | Activity | 是 | 当前 Activity |
req | SdkFinishPurchase | 是 | 完整支付上下文,见 5.1;推荐 payResult.toFinishPurchase(productType) |
callback | (SdkResult<Unit>) -> Unit | 是 | 确认结果 |
接口:trackEvent
kotlin
fun trackEvent(name: String, parameters: Map<String, String> = emptyMap())| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | String | 是 | 事件名 |
parameters | Map<String, String> | 否 | 事件参数,默认空 Map |
接口:getUser
kotlin
fun getUser(): SdkLoginResp?接口:getConfig
kotlin
fun getConfig(): SdkInitResp?接口:sdkAd
kotlin
fun sdkAd(): SdkAdApi?接口:sdkInfo
kotlin
fun sdkInfo(): SdkInfoApi?接口:setUiProxy
kotlin
fun setUiProxy(proxy: SdkUiProxy?)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
proxy | SdkUiProxy? | 是 | 仅接管 Toast / Loading;无 UI 门面本身仍不弹 screens。传 null 取消代理 |
调用示例
Kotlin
kotlin
import com.zeus.sdk.api.SdkHeadless
import com.zeus.sdk.api.SdkLoginPlatform
import com.zeus.sdk.api.SdkOption
import com.zeus.sdk.api.isSuccess
import com.zeus.sdk.pay.PayProductType
import com.zeus.sdk.pay.toFinishPurchase
import com.zeus.sdk.ui.SdkUiProxy
SdkHeadless.setUiProxy(object : SdkUiProxy {
override fun showToast(message: String) {}
override fun showLoading(message: String) {}
override fun dismissLoading() {}
})
SdkHeadless.init(
this,
SdkOption(dev = true, appId = 10000, lang = "en", gdpr = false, debug = true),
) { result ->
if (!result.isSuccess()) return@init
}
SdkHeadless.guestLogin(this) { }
SdkHeadless.tokenLogin(this) { }
SdkHeadless.thirdLogin(this, SdkLoginPlatform.GOOGLE) { }
SdkHeadless.partnerLogin(this, "partner_user_001") { }
SdkHeadless.bindThird(this, SdkLoginPlatform.GOOGLE) { }
SdkHeadless.logout(this) { }
SdkHeadless.purchase(this, "test_sku_001", PayProductType.IN_APP) { result ->
val pay = result.data ?: return@purchase
if (pay.clientSendReward) {
SdkHeadless.finishPurchase(this, pay.toFinishPurchase(PayProductType.IN_APP)) { }
}
}
SdkHeadless.queryPendingPurchases(this) { query ->
if (query.data.isNullOrEmpty()) return@queryPendingPurchases
SdkHeadless.processPendingPurchases(this) { }
}
SdkHeadless.trackEvent("level_complete", mapOf("level" to "3"))Java
java
import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.zeus.sdk.api.SdkHeadless;
import com.zeus.sdk.api.SdkLoginPlatform;
import com.zeus.sdk.api.SdkOption;
import com.zeus.sdk.api.SdkPendingPurchase;
import com.zeus.sdk.api.SdkResultKt;
import com.zeus.sdk.datas.SdkPayResult;
import com.zeus.sdk.pay.PayProductType;
import com.zeus.sdk.pay.SdkFinishPurchaseKt;
import com.zeus.sdk.ui.SdkUiProxy;
// 在 Activity 内调用;this 为当前 Activity
SdkHeadless.INSTANCE.setUiProxy(new SdkUiProxy() {
@Override
public void showToast(String message) {}
@Override
public void showLoading(String message) {}
@Override
public void dismissLoading() {}
});
SdkHeadless.INSTANCE.init(
this,
new SdkOption(true, 10000, "en", false, null, true),
result -> {
if (!SdkResultKt.isSuccess(result)) {
return null;
}
return null;
}
);
SdkHeadless.INSTANCE.guestLogin(this, result -> null);
SdkHeadless.INSTANCE.tokenLogin(this, result -> null);
SdkHeadless.INSTANCE.thirdLogin(this, SdkLoginPlatform.GOOGLE, result -> null);
SdkHeadless.INSTANCE.partnerLogin(this, "partner_user_001", result -> null);
SdkHeadless.INSTANCE.bindThird(this, SdkLoginPlatform.GOOGLE, result -> null);
SdkHeadless.INSTANCE.logout(this, result -> null);
SdkHeadless.INSTANCE.purchase(this, "test_sku_001", PayProductType.IN_APP, null, result -> {
SdkPayResult pay = result.getData();
if (pay == null) {
return null;
}
if (pay.getClientSendReward()) {
SdkHeadless.INSTANCE.finishPurchase(
this,
SdkFinishPurchaseKt.toFinishPurchase(pay, PayProductType.IN_APP),
finishResult -> null
);
}
return null;
});
SdkHeadless.INSTANCE.queryPendingPurchases(this, query -> {
List<SdkPendingPurchase> pending = query.getData();
if (pending == null || pending.isEmpty()) {
return null;
}
SdkHeadless.INSTANCE.processPendingPurchases(this, process -> null);
return null;
});
Map<String, String> params = Collections.singletonMap("level", "3");
SdkHeadless.INSTANCE.trackEvent("level_complete", params);5.4 广告与设备信息
通过 SDK.sdkAd() / SdkHeadless.sdkAd() 取得 SdkAdApi(需 plugin-applovin)。
通过 sdkInfo() 取得 SdkInfoApi。
接口:setAdListener
kotlin
fun setAdListener(listener: SdkAppLovinAdListener?)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
listener | SdkAppLovinAdListener? | 是 | 广告生命周期回调;传 null 清空 |
SdkAppLovinAdListener 常用回调参数:
| 回调 | 参数 | 说明 |
|---|---|---|
onAdLoaded | format | 加载成功 |
onAdLoadFailed | format, errorMessage | 加载失败 |
onAdDisplayed / onAdHidden / onAdClicked / onAdExpired | format | 展示 / 关闭 / 点击 / 过期 |
onUserRewarded | format, label, amount | 激励发放 |
接口:preloadAd
kotlin
fun preloadAd(format: SdkAdFormat)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
format | SdkAdFormat | 是 | 要预加载的广告格式 |
接口:isAdReady
是否已缓存可展示
kotlin
fun isAdReady(format: SdkAdFormat): Boolean| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
format | SdkAdFormat | 是 | 查询格式 |
接口:showAppOpenAd
kotlin
fun showAppOpenAd(placement: String? = null): Boolean| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
placement | String? | 否 | 广告位标识,便于统计;默认 null |
接口:showInterstitialAd
kotlin
fun showInterstitialAd(placement: String? = null): Boolean| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
placement | String? | 否 | 广告位标识,便于统计;默认 null |
接口:showRewardedAd
kotlin
fun showRewardedAd(placement: String? = null): Boolean| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
placement | String? | 否 | 广告位标识,便于统计;默认 null |
接口:attachBannerAd
kotlin
fun attachBannerAd(container: Any, placement: String? = null)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
container | Any(通常为 ViewGroup) | 是 | 广告容器 |
placement | String? | 否 | 广告位标识 |
接口:detachBannerAd
销毁Banner广告和组件
接口:loadNativeAd
kotlin
fun loadNativeAd(container: Any, placement: String? = null)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
container | Any(通常为 ViewGroup) | 是 | 广告容器 |
placement | String? | 否 | 广告位标识 |
接口:destroyNativeAd
销毁Native广告和组件
接口:sdkInfo()
对象方法如下:
| 方法 | 说明 |
|---|---|
getAdvertisingId() | Google Advertising ID |
getAndroidId() | Android ID |
getDeviceId() | SDK 设备 ID |
getAdjustId() | Adjust ID(需 plugin-adjust) |
getIdfa() / getIdfv() | iOS 字段,Android 一般为空 |
5.5 对照小结
| 能力 | SDK(有 UI) | SdkHeadless(无 UI) |
|---|---|---|
| 初始化 | init(ctx, config, callback) | 同左(锁定不弹 screens) |
| 登录 | login(ctx, callback) | guestLogin / tokenLogin / thirdLogin(platform) / partnerLogin(partnerUserId) |
| 绑定 | bindThird(ctx, callback) | bindThird(ctx, platform, callback) |
| 切号 | switchAccount(ctx, callback) | 无(自行 logout 再登录) |
| 登出 | logout(ctx, callback) | 同左 |
| 支付 | purchase(ctx, skuId, productType, metadata?, callback) | 同左 |
| 确认发奖 | finishPurchase(ctx, req, callback) | 同左 |
| 补单 | processPendingPurchases(一步) | queryPendingPurchases → processPendingPurchases |
| 埋点 / 广告 / 设备信息 | 有 | 有 |
| UI | 内置 screens;setUiProxy 可跳过登录页 | 不弹 screens;setUiProxy 只管 Loading/Toast |