Android SDK
Kotlin SDK 参考 — Play Billing Library 6.0+ 集成。
前置条件
- minSdk 24+
- Play Billing Library 6.0+(SDK 已内置依赖)
- 控制台中的 Publishable Key(pk_live_... 或 pk_test_...)
安装
在 app/build.gradle.kts 中添加 Maven Central 依赖:
build.gradle.kts
dependencies {
implementation("dev.subhub:sdk:1.0.0")
}configure(context, publishableKey)
初始化 SDK。必须在其他方法之前调用,通常在 Application.onCreate() 中执行。
需要传入 Application Context 与控制台中的 Publishable Key。
Kotlin
import dev.subhub.SubHub
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
SubHub.configure(this, "pk_live_focustimer_android_8f3k2m")
}
}identify(developerUserId?)
关联开发者提供的 opaque 用户标识。平台不解析此字符串 — 可为 UUID、email、Firebase UID 等。
未调用 identify 时,成员仅以 anonymousId 标识。登出时传 null 解除关联。
SubHub.identify("firebase_uid_8a2b")
// 登出时解除关联
SubHub.identify(null)purchase(productId)
发起 Google Play 应用内购买。productId 为 Play Console 中的 Product ID,非 SubHub 内部 ID。
SDK 处理 Play Billing 交互,购买完成后自动将 purchase token 提交至 SubHub 验证。
需在 Activity 上下文中调用,SDK 内部会 launchBillingFlow。
// 在 Activity 或 Fragment 中
lifecycleScope.launch {
val result = SubHub.purchase(
activity = this@MainActivity,
productId = "com.neo.focustimer.promo"
)
Log.d("SubHub", result.purchaseId)
Log.d("SubHub", result.entitlements.toString())
}restore()
恢复用户历史 Google Play 购买。适用于换机或重装场景。
lifecycleScope.launch {
SubHub.restore()
val entitlements = SubHub.entitlements()
}entitlements()
返回当前成员持有的所有 Entitlement 实例。
lifecycleScope.launch {
val entitlements = SubHub.entitlements()
entitlements.forEach { ent ->
Log.d("SubHub", "${ent.identifier}: ${ent.isActive}")
}
}hasEntitlement(key)
检查成员是否持有指定 Entitlement。这是客户端鉴权的推荐方式。
不要使用 hasProduct() — 业务逻辑应基于 Entitlement,而非 Product。
lifecycleScope.launch {
if (SubHub.hasEntitlement("premium")) {
showPremiumContent()
}
}错误处理
SDK 抛出 SubHubException,常见情况包括网络失败、用户取消购买、凭证验证失败等。
lifecycleScope.launch {
try {
val result = SubHub.purchase(activity, "com.app.promo")
} catch (e: SubHubException.UserCancelled) {
// 用户取消
} catch (e: SubHubException.VerificationFailed) {
// 凭证验证失败
} catch (e: SubHubException) {
// 其他错误
}
}